Skip to content

Local model management is disabled on Windows because the models directory is resolved from $HOME #3761

Closed

Description

@malibio

Overview

On Windows, the daemon logs an error at every startup and runs with local GGUF model management disabled, because the models directory is resolved from the HOME environment variable, which Windows does not set for ordinary processes.

Problem Statement

Observed on the published v0.3.5 Windows installer (NodeSpace_0.3.5_x64_en-US.msi), release build, Windows 11 ARM64 VM running the x64 build under emulation. The daemon's log (%USERPROFILE%\.nodespace\logs\) shows:

ERROR nodespace_daemon::services::local_agent_service: GgufModelManager initialization failed — local GGUF model management disabled (chat turns and OpenAI-compatible models are unaffected) error=could not determine models directory: $HOME is unset

In the same run, the daemon resolved its database path and the embedding model path under C:\Users\<user>\.nodespace\ without trouble. So the daemon has a working home-directory resolver, and the models directory is the one place that bypasses it.

Root cause: default_models_dir() in packages/agent/src/local_agent/model_manager.rs reads std::env::var("HOME") and fails when it is absent. Windows sets USERPROFILE, not HOME. Its doc comment says the models directory is "consistent with the database path ... Both paths honour $HOME", which is no longer true: the daemon's nodespace_home() (packages/daemon/src/lib.rs) honours NODESPACE_HOME and then falls back to dirs::home_dir(), which is correct on every platform.

Effect: GgufModelManager is not created on Windows, so local GGUF model management (list, download, load of local models) is unavailable there. The log states that chat turns and OpenAI-compatible models are unaffected.

Proposed Solution

Resolve the models directory the same way the database path is resolved, so a single override (NODESPACE_HOME) redirects all NodeSpace state and Windows works without HOME.

Documentation

  • ADR-053 - the NODESPACE_HOME single-override rule for state under .nodespace/
  • No prior ADR or architecture doc found covering how the models directory is resolved.

Acceptance Criteria

  • With HOME unset and USERPROFILE set (the normal Windows environment), GgufModelManager initializes and the daemon logs no $HOME is unset error
  • The models directory follows NODESPACE_HOME when it is set, matching the database path
  • The models directory and the embedding model path (~/.nodespace/models/) are one resolution, not two parallel ones
  • The existing degraded-mode tests still pass: a plain file occupying the models path must still degrade cleanly, without a panic
  • A test covers the resolver with HOME unset (mutation-check it: it must fail on the current HOME-only code)
  • The default_models_dir doc comment, and any other comment or doc line that says the models path "honours $HOME", is corrected
  • Code passes bun run quality:fix

Technical Specifications

Reference Files

  • packages/agent/src/local_agent/model_manager.rs (default_models_dir, line ~799, called from GgufModelManager::new at line ~144) - the HOME-only read
  • packages/daemon/src/lib.rs (nodespace_home, nodespace_dir, resolve_db_path) - the resolver the models directory should share
  • packages/daemon/src/services/local_agent_service.rs (test shared_local_agent_new_survives_a_real_model_manager_init_failure, line ~8200) - redirects the models path by setting HOME; it needs to redirect through the new resolution instead

Implementation Details

  • nodespace-daemon depends on nodespace-agent, not the reverse, and nodespace-agent already has dirs. So either the models directory is passed in by the daemon (which already owns nodespace_home), or nodespace-agent gains an equivalent that honours NODESPACE_HOME then dirs::home_dir(). The first avoids a second copy of the rule.
  • Establish the size first, as the workflow asks: from reading the code this looks like a small change (one function and one test), but I have not tried it.

Other HOME-only reads worth a look (not verified as bugs)

  • packages/agent/src/pty/session.rs:78 - BASE_ENV_ALLOWLIST forwards HOME but not USERPROFILE to PTY child processes. Whether that matters on Windows depends on how the allowlist is applied there.

Related Issues

Activity

  1. malibio commented on Oct 12, 2026

    @malibio
    CollaboratorAuthor

    Frontend baseline: 325 files, 5897 tests passed (bun run test, worktree issue-3761-models-dir-home, main at af46b30)

  2. self-assigned this
    on Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions