{"record":{"id":"807f569805079bac","repo":"gethomepage/homepage","slug":"unsupported-config-file-file-supported-files","errorCode":null,"errorMessage":"Unsupported config file '${file}'. Supported files: ${CONFIG_FILES.join(\", \")}","messagePattern":"Unsupported config file '(.+?)'\\. Supported files: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/utils/mcp/homepage-mcp.js","lineNumber":102,"sourceCode":"      ...(data ? { data } : {}),\n    },\n  };\n}\n\nfunction textContent(text) {\n  return {\n    content: [\n      {\n        type: \"text\",\n        text,\n      },\n    ],\n  };\n}\n\nfunction assertKnownConfigFile(file) {\n  if (!CONFIG_FILES.includes(file)) {\n    throw new Error(`Unsupported config file '${file}'. Supported files: ${CONFIG_FILES.join(\", \")}`);\n  }\n}\n\nfunction configPath(file) {\n  assertKnownConfigFile(file);\n  return join(CONF_DIR, file);\n}\n\nfunction fileExists(file) {\n  return existsSync(configPath(file));\n}\n\nfunction readConfig(file) {\n  const path = configPath(file);\n  return existsSync(path) ? readFileSync(path, \"utf8\") : \"\";\n}\n\nfunction parseYamlConfig(file) {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/gethomepage/homepage/blob/b6dca1ae033e613d8e692f9a161a3cc53a5a2857/src/utils/mcp/homepage-mcp.js#L84-L120","documentation":"Thrown by the MCP server's config-file guard when a caller names a file that isn't in the hardcoded CONFIG_FILES allowlist (settings.yaml, services.yaml, bookmarks.yaml, widgets.yaml, docker.yaml, kubernetes.yaml, proxmox.yaml, custom.css, custom.js). It exists to keep MCP reads/writes inside Homepage's known config surface.","triggerScenarios":"assertKnownConfigFile(file) is called from configPath(), readConfig(), write_config_file, validate_config_file, or resources/read, and the passed filename is not in CONFIG_FILES. e.g. tool call `read_config_file` with file='settings.yml', 'services.json', '../settings.yaml', or 'custom.html'.","commonSituations":"Client uses .yml extension instead of .yaml; caller tries a relative path or directory traversal; typo in filename; user assumes a file exists (e.g. 'theme.yaml') that Homepage never supported; MCP client auto-suggests an unrelated filename.","solutions":["Use one of the listed filenames exactly (case-sensitive, .yaml not .yml).","Call list_config_files first to see the allowlist at runtime.","Don't pass paths or query strings — only the bare filename.","If you genuinely need a new config file, it must be added to CONFIG_FILES in homepage-mcp.js first."],"exampleFix":"// before\n{ \"file\": \"settings.yml\" }\n\n// after\n{ \"file\": \"settings.yaml\" }","handlingStrategy":"validation","validationCode":"const CONFIG_FILES = ['settings.yaml','services.yaml','bookmarks.yaml','widgets.yaml','docker.yaml','kubernetes.yaml','proxmox.yaml','custom.css','custom.js'];\nfunction isKnownConfigFile(file) {\n  return CONFIG_FILES.includes(file);\n}\n// before calling read/write:\nif (!isKnownConfigFile(file)) throw new Error(`Use one of: ${CONFIG_FILES.join(', ')}`);","typeGuard":"function isKnownConfigFile(file) {\n  return typeof file === 'string' && CONFIG_FILES.indexOf(file) !== -1;\n}","tryCatchPattern":null,"preventionTips":["Call list_config_files first to enumerate valid names.","Never construct filenames from untrusted input.","Normalize extension to .yaml (not .yml) before calling.","Document the allowlist next to MCP client code."],"tags":["mcp","configuration","validation","filesystem"],"backgroundTag":null,"analyzedSha":"b6dca1ae033e613d8e692f9a161a3cc53a5a2857","analyzedAt":"2026-08-13T04:48:44.121Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}