{"record":{"id":"053072c27178271c","repo":"sipeed/picoclaw","slug":"instance-root-resolved-to-current-directory","errorCode":null,"errorMessage":"instance root resolved to current directory","messagePattern":"instance root resolved to current directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/isolation/runtime.go","lineNumber":72,"sourceCode":"\t\tcurrentIsolation = defaults.Isolation\n\t\treturn\n\t}\n\tcurrentIsolation = cfg.Isolation\n}\n\n// CurrentConfig returns the currently active isolation settings.\nfunc CurrentConfig() config.IsolationConfig {\n\tisolationMu.RLock()\n\tdefer isolationMu.RUnlock()\n\treturn currentIsolation\n}\n\n// ResolveInstanceRoot resolves the instance root used to build the isolated\n// filesystem and redirected user environment.\nfunc ResolveInstanceRoot() (string, error) {\n\troot := filepath.Clean(config.GetHome())\n\tif root == \".\" {\n\t\treturn \"\", fmt.Errorf(\"instance root resolved to current directory\")\n\t}\n\treturn root, nil\n}\n\n// PrepareInstanceRoot creates the directories required by the isolation runtime.\nfunc PrepareInstanceRoot(root string) error {\n\tfor _, dir := range InstanceDirs(root) {\n\t\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\t\treturn fmt.Errorf(\"prepare instance dir %s: %w\", dir, err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// InstanceDirs returns the directories that must exist under the instance root\n// for isolation-aware child processes.\nfunc InstanceDirs(root string) []string {\n\tdirs := []string{","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/isolation/runtime.go#L54-L90","documentation":"ResolveInstanceRoot derives the isolation instance root from config.GetHome(). GetHome uses the PICOCLAW_HOME env var when set; otherwise the OS user home plus the default picoclaw home directory. When both resolve to nothing (no PICOCLAW_HOME, os.UserHomeDir() fails because HOME/USERPROFILE is unset), GetHome returns \".\", and preflight rejects it: building an isolated filesystem relative to the current working directory is unsafe, so the error is returned instead.","triggerScenarios":"Preflight()/ResolveInstanceRoot() called with isolation enabled while (a) HOME (Unix) or USERPROFILE (Windows) is unset or empty and (b) PICOCLAW_HOME is unset — typical in systemd services, cron jobs, Docker containers, or launchd plists that scrub the environment; or PICOCLAW_HOME explicitly set to an empty string.","commonSituations":"Running the binary as a systemd unit without EnvironmentFile setting HOME; Docker images with no HOME baked in; CI pipelines; running via sudo with env_reset; daemonizing from a supervisor that passes a minimal env.","solutions":["Set PICOCLAW_HOME to an absolute, writable directory (e.g. /var/lib/picoclaw) in the service environment","Otherwise ensure HOME (Unix) / USERPROFILE (Windows) is set for the account running the process","For containers/servers, add the env directive to the unit file or Dockerfile","Do not rely on cwd: the check intentionally rejects the fallback to \".\""],"exampleFix":"# before: systemd unit with scrubbed env\n[Service]\nExecStart=/usr/local/bin/picoclaw\n\n# after\n[Service]\nEnvironment=\"PICOCLAW_HOME=/var/lib/picoclaw\"\nExecStart=/usr/local/bin/picoclaw","handlingStrategy":"validation","validationCode":"// before enabling isolation, verify the instance root can be resolved\nfunc instanceRootResolvable() bool {\n    if os.Getenv(\"PICOCLAW_HOME\") != \"\" {\n        return true\n    }\n    home, err := os.UserHomeDir()\n    return err == nil && home != \"\"\n}","typeGuard":null,"tryCatchPattern":"root, err := isolation.ResolveInstanceRoot()\nif err != nil {\n    return fmt.Errorf(\"cannot determine instance root — set PICOCLAW_HOME or HOME in the service environment: %w\", err)\n}","preventionTips":["Always set PICOCLAW_HOME explicitly in services, containers, cron and CI environments","Never assume HOME survives into daemons — systemd, launchd and docker scrub or omit it","Fail startup early with a clear message instead of discovering the missing env at first isolated launch"],"tags":["config","environment","isolation","filesystem"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}