{"record":{"id":"ab3ac4a975e6f9d5","repo":"multica-ai/multica","slug":"daemon-managed-task-requires-a-task-local-multica","errorCode":null,"errorMessage":"daemon-managed task requires a task-local Multica config root in %s%s","messagePattern":"daemon-managed task requires a task-local Multica config root in (.+?)(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_agent.go","lineNumber":415,"sourceCode":"\treturn \"; MULTICA_DAEMON_PORT is set without task identity — if this is a host or container startup shell, remove that variable and retry\"\n}\n\n// requireTaskLocalConfigRoot prevents daemon-managed subprocesses that lost\n// part of their injected environment from silently resolving Multica state\n// below the daemon owner's HOME. Commands that intentionally support task-local\n// config (currently config show/set and auth status) call this before any load.\nfunc requireTaskLocalConfigRoot() error {\n\tif !inDaemonManagedExecutionContext() {\n\t\treturn nil\n\t}\n\tif strings.TrimSpace(os.Getenv(cli.TaskConfigRootEnv)) == \"\" {\n\t\t// The third refusal path a leftover marker can trigger, alongside\n\t\t// newAPIClient and requireHumanLocalCommand. It has to name the file\n\t\t// too: a user hitting this one through `config show` or `auth status`\n\t\t// is as stuck as one hitting the others, and \"which command did you\n\t\t// happen to run first\" must not decide whether the error is actionable.\n\t\tif markerPath := leftoverDaemonTaskMarkerPath(); markerPath != \"\" {\n\t\t\treturn fmt.Errorf(\"daemon-managed task requires a task-local Multica config root in %s%s\", cli.TaskConfigRootEnv, leftoverMarkerSuffix(markerPath))\n\t\t}\n\t\treturn fmt.Errorf(\"daemon-managed task requires a task-local Multica config root in %s%s\", cli.TaskConfigRootEnv, daemonPortOnlyContextHint())\n\t}\n\treturn nil\n}\n\n// requireHumanLocalCommand rejects commands whose purpose is to authenticate,\n// set up, or operate the human-owned local daemon/profile. Task API commands\n// remain available with the injected mat_ token; these local commands do not.\nfunc requireHumanLocalCommand(command string) error {\n\tif !inDaemonTaskIdentityContext() {\n\t\treturn nil\n\t}\n\t// A task-scoped workdir marker with no task identity in the environment is\n\t// the one signal that can outlive the task that wrote it: a local_directory\n\t// run that never cleaned up leaves it in the user's own repository, where it\n\t// disables every command below this function for that whole directory tree\n\t// until someone deletes the file by hand (MUL-6132). Name it, so the user","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_agent.go#L397-L433","documentation":"requireTaskLocalConfigRoot guards config-reading commands (config show, auth status, etc.) in daemon-managed execution: they must load from the task-local config root injected via cli.TaskConfigRootEnv, never the human's global config. This variant fires when a leftover workdir marker is the only daemon signal, and names the exact marker file so the user can recover.","triggerScenarios":"inDaemonManagedExecutionContext() is true purely from a stale marker file (crashed local_directory daemon task), the TaskConfigRootEnv variable is empty/unset, and the user runs a config command in that directory tree.","commonSituations":"Same MUL-6132 leftover-marker situation as newAPIClient's refusal, hit through `multica config show` or `multica auth status` instead of an API command; deliberately parallel wording so which command ran first does not change actionability.","solutions":["Delete the marker file named in the appended leftoverMarkerSuffix.","Re-run the config command from outside the affected directory tree to confirm recovery.","If you actually are inside a real daemon task, ensure the daemon exports the task-local config root in the env var named in the message before running config commands."],"exampleFix":"# before\nmultica config show\n# -> daemon-managed task requires a task-local Multica config root in ...\n\n# after\nrm /path/to/repo/.multica/daemon-task-marker.json\nmultica config show","handlingStrategy":"validation","validationCode":"# Before `multica config show` in any repo, confirm no stale marker exists:\nif find . -name daemon-task-marker.json -path '*/.multica/*' | grep -q .; then\n  echo \"stale daemon marker present; remove it before running config commands\" >&2\n  exit 1\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Delete stale markers after crashed local_directory tasks instead of leaving them in the repo.","Prefer running human config commands from $HOME or a clean directory.","Automate marker cleanup in task-failure handlers."],"tags":["go","cli","configuration","daemon","environment"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}