{"record":{"id":"e341b28ea1daa914","repo":"tinyhumansai/openhuman","slug":"provider-unavailable-reason","errorCode":null,"errorMessage":"provider unavailable: {reason}","messagePattern":"provider unavailable: (.+?)","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/core/subconscious_cli.rs","lineNumber":141,"sourceCode":"                eprintln!(\"[subconscious] session token found — provider available\");\n            }\n            Ok(None) => {\n                eprintln!(\"[subconscious] WARNING: no session token — cloud provider will fail\");\n                eprintln!(\"  hint: run `openhuman call auth store_session --token <JWT>` first\");\n            }\n            Err(e) => {\n                eprintln!(\"[subconscious] WARNING: session token read failed: {e}\");\n            }\n        }\n\n        // Check provider availability\n        if let Some(reason) =\n            crate::openhuman::subconscious::provider::subconscious_provider_unavailable_reason(\n                &config,\n            )\n        {\n            eprintln!(\"[subconscious] provider unavailable: {reason}\");\n            return Err(anyhow!(\"provider unavailable: {reason}\"));\n        }\n\n        // Create engine and run tick. The engine pulls its own memory_diff /\n        // context state from the workspace — no memory client to pass in.\n        let engine = crate::openhuman::subconscious::memory_instance(&config);\n\n        eprintln!(\"[subconscious] running tick...\");\n        let result = engine\n            .tick()\n            .await\n            .map_err(|e| anyhow!(\"tick failed: {e}\"))?;\n\n        eprintln!(\n            \"[subconscious] tick complete: duration={}ms response_chars={}\",\n            result.duration_ms, result.response_chars,\n        );\n\n        if flags.verbose {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/src/core/subconscious_cli.rs#L123-L159","documentation":"The subconscious CLI pre-flight check calls `subconscious_provider_unavailable_reason(&config)` (src/openhuman/subconscious/provider.rs:37) and hard-fails with the reason when Some. In practice the reason is one of: \"Sign in to use the OpenHuman cloud Subconscious provider.\" (scheduler gate says signed out), \"Sign in or configure a local Subconscious provider...\" (AuthService found no non-empty bearer for APP_SESSION_PROVIDER), or \"Unable to read the OpenHuman session: {e}\" (keyring/credential store error). It only fires when the resolved route is OpenHumanCloud — LocalOllama and Other provider routes always pass.","triggerScenarios":"`openhuman subconscious tick` (or the run path at src/core/subconscious_cli.rs:141) while `subconscious_provider` is unset/\"cloud\"/\"openhuman\" AND the user is signed out, has an empty/missing session token in the state dir next to config_path, or the credential store is unreadable. A local `subconscious` workload model in config bypasses the check entirely.","commonSituations":"Fresh install where the user never signed in; session token expired and cleared; state dir moved so AuthService::new points at a directory with no stored session; running the tick headless in CI/docker where no sign-in ever happened.","solutions":["Sign in to the app so the APP_SESSION_PROVIDER bearer token exists and `is_signed_out()` is false.","Or configure a local provider: set a `subconscious` workload model (Ollama) in Connections → API keys → LLM, which routes LocalOllama and skips the auth check.","Or set `subconscious_provider` to a non-cloud provider string so the route resolves to Other.","If the reason says 'Unable to read the OpenHuman session', fix the credential store permissions/path (state dir is config_path's parent, falling back to workspace_dir).","Verify first with `openhuman subconscious status` — it prints the same provider_reason only when the mode is enabled."],"exampleFix":"# before\nopenhuman subconscious tick   # signed out, cloud route -> provider unavailable\n# after: sign in via the app, or pin a local model in config.toml\n[workload_models]\nsubconscious = \"ollama://localhost:11434/llama3.1\"","handlingStrategy":"validation","validationCode":"// Pre-flight the same check the CLI makes (provider.rs): run\n// `openhuman subconscious status` first and require a healthy provider\n// before ticking:\n//   openhuman subconscious status   # prints provider state when mode enabled\n// In-process callers can call\n//   subconscious_provider_unavailable_reason(&config)\n// (pub(crate) — exposed via SubconsciousStatus.provider_unavailable_reason over RPC)\n// and abort before engine construction when it returns Some.","typeGuard":null,"tryCatchPattern":"match run_tick().await {\n    Err(e) if e.to_string().starts_with(\"provider unavailable\") => {\n        // Re-run `status` to fetch the actionable reason and surface it;\n        // do not retry until sign-in or a local model is configured.\n    }\n    other => other,\n}","preventionTips":["Run `subconscious status` before tick in scripts and gate on healthy output.","Configure a local subconscious workload model for headless/CI so the cloud sign-in requirement disappears.","Keep the app signed in; watch for scheduler-gate sign-out after token expiry."],"tags":["rust","subconscious","authentication","provider-routing","cli"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}