{"record":{"id":"7ffda7ce27c2112a","repo":"xai-org/grok-build","slug":"notfound","errorCode":"NotFound","errorMessage":"no grok home","messagePattern":"no grok home","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/views/dashboard/state.rs","lineNumber":4334,"sourceCode":"        enabled,\n        grouping,\n        pinned,\n        reorder,\n    })\n}\n\n/// Synchronous, blocking write of the persisted dashboard config.\n/// Spawned from [`crate::app::actions::Effect`] handlers via `spawn_blocking`.\n///\n/// Short-circuits when `read_config_document_for_edit` returns `None`.\n/// That helper returns `None` only when the file is non-empty AND unparseable, meaning we\n/// MUST NOT overwrite it (the file may contain user data we cannot interpret).\n/// Without this guard, a single dashboard pin would clobber every other table in `~/.grok/config.toml` (`[ui]`, `[hints]`, `[mcpServers]`, …).\n///\n/// Atomic write via `<path>.dashboard.tmp.<pid>` then rename, so concurrent readers never observe a half-truncated file.\npub fn write_persisted(p: &PersistedDashboard) -> std::io::Result<()> {\n    let path = config_path()\n        .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, \"no grok home\"))?;\n    write_persisted_to_path(&path, p)\n}\n\n/// Path-taking variant of [`write_persisted`] so the on-disk round-trip can be exercised in tests against a `tempfile::TempDir`.\npub fn write_persisted_to_path(\n    path: &std::path::Path,\n    p: &PersistedDashboard,\n) -> std::io::Result<()> {\n    if let Some(parent) = path.parent() {\n        std::fs::create_dir_all(parent)?;\n    }\n    let mut doc = match crate::config_toml_edit::read_config_document_for_edit(path) {\n        Some(d) => d,\n        None => {\n            // File exists but is unparseable\n            // Refuse to overwrite; doing so would erase every other table\n            tracing::warn!(\n                path = %path.display(),","sourceCodeStart":4316,"sourceCodeEnd":4352,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/views/dashboard/state.rs#L4316-L4352","documentation":"`write_persisted` persists the dashboard state to `~/.grok/config.toml`. It first resolves the config path via `config_path()`, which returns `None` when the user's home directory (the 'grok home') cannot be determined. In that case it throws `std::io::Error` with kind `NotFound` and message 'no grok home' instead of writing to an arbitrary location.","triggerScenarios":"Calling `write_persisted` (e.g. when a user pins a table on the dashboard) while the `HOME` environment variable is unset (or the platform home-dir lookup fails), so `config_path()` returns `None`.","commonSituations":"Running the CLI in a container, cron job, systemd unit, or SSH session where `HOME` is not set; running under a service account with no home directory; sanitizing env vars in tests/CI which strips `HOME`.","solutions":["Set the `HOME` environment variable to an existing writable directory before running the tool","Run as a user that has a valid home directory (check with `echo $HOME` / `getent passwd <user>`)","In embedded/service contexts, pre-create the home dir and export `HOME=/path/to/it` in the unit/service env","If you cannot set HOME, avoid persisting dashboard pins and handle the io::Error kind NotFound gracefully"],"exampleFix":"// before\nsudo -u serviceuser grok dashboard   # HOME unset -> error\n// after\nsudo -u serviceuser env HOME=/home/serviceuser grok dashboard","handlingStrategy":"validation","validationCode":"if std::env::var_os(\"HOME\").is_none() {\n    eprintln!(\"HOME is not set; dashboard persistence will fail\");\n    std::process::exit(1);\n}","typeGuard":null,"tryCatchPattern":"match write_persisted(&dash) {\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound && e.to_string().contains(\"no grok home\") => {\n        eprintln!(\"Cannot persist dashboard: set $HOME\");\n    }\n    Err(e) => return Err(e.into()),\n    Ok(()) => {}\n}","preventionTips":["Always run with HOME set, even in containers/CI","For service units, set Environment=HOME=/home/user","Check `echo $HOME` when persistence errors appear"],"tags":["io","filesystem","environment","not-found"],"backgroundTag":"missing-env-var","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}