{"record":{"id":"de0c21b0dec83072","repo":"tobi/qmd","slug":"failed-to-write-configpath-error","errorCode":null,"errorMessage":"Failed to write ${configPath}: ${error}","messagePattern":"Failed to write (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/collections.ts","lineNumber":231,"sourceCode":"  if (configSource.type === 'inline') {\n    configSource.config = config;\n    return;\n  }\n\n  const configPath = configSource.path || getConfigFilePath();\n  const configDir = dirname(configPath);\n  if (!existsSync(configDir)) {\n    mkdirSync(configDir, { recursive: true });\n  }\n\n  try {\n    const yaml = YAML.stringify(config, {\n      indent: 2,\n      lineWidth: 0,  // Don't wrap lines\n    });\n    writeFileSync(configPath, yaml, \"utf-8\");\n  } catch (error) {\n    throw new Error(`Failed to write ${configPath}: ${error}`);\n  }\n}\n\n/**\n * Get a specific collection by name\n * Returns null if not found\n */\nexport function getCollection(name: string): NamedCollection | null {\n  const config = loadConfig();\n  const collection = config.collections[name];\n\n  if (!collection) {\n    return null;\n  }\n\n  return { name, ...collection };\n}\n","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/tobi/qmd/blob/dbfd0b4736aeaf761d1a16ca8e424f071df8feb9/src/collections.ts#L213-L249","documentation":"saveConfig could not write the serialized YAML config to disk; writeFileSync threw (EACCES, ENOSPC, EISDIR, readonly path, etc.) and the error is wrapped with the target path. It is raised by every operation that mutates collections (add/remove/rename, settings updates).","triggerScenarios":"Running qmd collection add/remove/rename when the config path is read-only, owned by another user, on a full disk, or when the path is a directory.","commonSituations":"Configs under a root-owned /etc or ~/.config after running qmd once with sudo; disk-full CI runners; immutable container filesystems; two qmd processes racing on the same config.","solutions":["Check permissions/ownership of the config path named in the message and chown/chmod it","Free disk space or remount the filesystem read-write","Avoid running qmd with sudo so configs aren't written as root","Pass an explicit writable configPath when running in containers/CI"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { accessSync, constants } from 'node:fs';\nimport { dirname } from 'node:path';\n\nfunction configWritable(configPath: string): boolean {\n  try {\n    accessSync(dirname(configPath), constants.W_OK);\n    return true;\n  } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await store.addCollection?.(name, path);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Failed to write')) {\n    // show path, check permissions/disk, surface to user\n  } else throw e;\n}","preventionTips":["Never run qmd with sudo","Ensure the config directory is user-writable","Keep disk space monitored on CI/long-running machines"],"tags":["filesystem","config","permissions","io"],"backgroundTag":"file-write-permission-denied","analyzedSha":"dbfd0b4736aeaf761d1a16ca8e424f071df8feb9","analyzedAt":"2026-08-28T18:07:46.628Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}