coleam00/Archon · error
Pi auth storage init failed: ${e.message}. Check that ~/.pi/
Error message
Pi auth storage init failed: ${e.message}. Check that ~/.pi/agent/auth.json (or $PI_CODING_AGENT_DIR/auth.json) is valid JSON and readable. What it means
sendQuery constructs a Pi ModelRuntime backed by the auth storage (~/.pi/agent/auth.json or $PI_CODING_AGENT_DIR/auth.json). If that construction throws (malformed JSON, unreadable file, bad permissions), the error is rethrown with guidance pointing at the auth file, preserving the original message and logging pi.auth_storage_init_failed.
Source
Thrown at packages/providers/src/community/pi/provider.ts:465
// there first and fall back to process.env for a shell-level override.
const archonAuthPath =
(requestOptions?.env?.ARCHON_PI_AUTH_PATH ?? process.env.ARCHON_PI_AUTH_PATH)?.trim() ||
undefined;
// pi-coding-agent 0.84.0 folded AuthStorage + ModelRegistry into a single
// ModelRuntime; ModelRegistry is now a thin facade constructed from a
// runtime. authPath still feeds the file-backed CredentialStore inside
// ModelRuntime — the per-user auth.json path is honoured the same way.
// modelsPath follows the same per-call pattern for custom providers'
// `${VAR}` substitution.
modelRuntime = await piCodingAgent.ModelRuntime.create({
authPath: archonAuthPath,
...(customProviderModelsPath ? { modelsPath: customProviderModelsPath } : {}),
});
modelRegistry = new piCodingAgent.ModelRegistry(modelRuntime);
} catch (err) {
const e = err as Error;
getLog().error({ err: e, piProvider: parsed.provider }, 'pi.auth_storage_init_failed');
throw new Error(
`Pi auth storage init failed: ${e.message}. Check that ~/.pi/agent/auth.json ` +
'(or $PI_CODING_AGENT_DIR/auth.json) is valid JSON and readable.'
);
} finally {
// The per-call models.json holds the literal substituted secret in
// cleartext. ModelRuntime.create reads it once at construction (via
// ModelConfig.load); the runtime carries the loaded values for the
// rest of the session, so the file can be removed as soon as the
// create() promise resolves. Without this cleanup, long-running
// processes accumulate one file per sendQuery and eventually hit
// ENOSPC, after which buildCustomProviderModelsPath's mkdirSync fails
// and the SDK silently falls through to the unsubstituted user
// models.json — re-opening the round-1 R1 leak surface. Errors here
// are non-fatal (the file may already be gone, or the FS may be in
// an odd state); the original error has already been surfaced.
if (customProviderModelsPath) {
try {
rmSync(customProviderModelsPath, { force: true });View on GitHub (pinned to 0773b97458)
Solutions
- Validate ~/.pi/agent/auth.json parses as JSON (e.g. `jq . ~/.pi/agent/auth.json`); fix or delete it and re-run `pi /login`
- Check file permissions (readable by the running user)
- If PI_CODING_AGENT_DIR is set, check auth.json at $PI_CODING_AGENT_DIR/auth.json instead
- Restore auth.json by running `pi` and `/login` to regenerate it
Example fix
// before (truncated file)
{"anthropic": {"type": "oauth", "access"
// after
$ rm ~/.pi/agent/auth.json && pi # then /login Defensive patterns
Strategy: try-catch
Validate before calling
import { readFileSync } from 'node:fs';
const authPath = process.env.PI_CODING_AGENT_DIR
? `${process.env.PI_CODING_AGENT_DIR}/auth.json` : `${process.env.HOME}/.pi/agent/auth.json`;
try {
JSON.parse(readFileSync(authPath, 'utf8'));
} catch (e) {
throw new Error(`Pi auth file unreadable/invalid at ${authPath}: ${e.message}; run 'pi' + /login to regenerate`);
} Type guard
function isReadableJsonFile(path: string): boolean {
try { JSON.parse(readFileSync(path, 'utf8')); return true; } catch { return false; }
} Try / catch
try {
await sendQuery(q);
} catch (err) {
if (err.message.startsWith('Pi auth storage init failed')) {
log.error({ cause: err }, 'pi auth file invalid; regenerating via pi /login is required');
}
throw err;
} Prevention
- Never hand-edit auth.json; use `pi /login` to write it
- Back up auth.json before provisioning changes
- Check auth.json health (JSON.parse) in a startup health check
- Avoid processes that truncate-write shared files like sync tools
When it happens
Trigger: sendQuery when auth.json contains invalid JSON (e.g. from a truncated write or hand edit), has wrong permissions, is a directory, or PI_CODING_AGENT_DIR points somewhere without a readable auth.json.
Common situations: Hand-editing ~/.pi/agent/auth.json and breaking JSON, syncing tools copying partial files, permissions changed by chown/chmod, or a custom PI_CODING_AGENT_DIR with a stale/invalid auth file.
Related errors
- Pi auth: no credentials for provider '${parsed.provider}'. $
- Repository ${owner}/${repo} not found or is private. Check r
- Authentication failed for ${owner}/${repo}. Check GITEA_TOKE
- tar extraction failed (exit ${exitCode}): ${details}
- Failed to move extracted web UI from ${tmpDir} to ${targetDi
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/81a368720b94ea28.
Report an issue: GitHub.