{"record":{"id":"7c4091796d88c90b","repo":"itwanger/toBeBetterJavaer","slug":"missing-required-env-vars-missing-join","errorCode":null,"errorMessage":"Missing required env vars: ${missing.join(\", \")}","messagePattern":"Missing required env vars: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"scripts/convert-mdnice-images-to-cdn.js","lineNumber":168,"sourceCode":"    ) {\n      value = value.slice(1, -1);\n    }\n    env[key] = value;\n  }\n  return env;\n}\n\nfunction validateOssConfig(config) {\n  const required = [\n    \"PAICODING_OSS_AK\",\n    \"PAICODING_OSS_SK\",\n    \"PAICODING_OSS_ENDPOINT\",\n    \"PAICODING_OSS_BUCKET\",\n    \"PAICODING_OSS_HOST\",\n  ];\n  const missing = required.filter((key) => !config[key]);\n  if (missing.length > 0) {\n    throw new Error(`Missing required env vars: ${missing.join(\", \")}`);\n  }\n}\n\nfunction collectMarkdownFiles(targets) {\n  const files = [];\n  for (const target of targets) {\n    if (!fs.existsSync(target)) {\n      throw new Error(`Path not found: ${target}`);\n    }\n    const stat = fs.statSync(target);\n    if (stat.isDirectory()) {\n      walkDir(target, files);\n    } else if (target.endsWith(\".md\")) {\n      files.push(target);\n    }\n  }\n  return [...new Set(files)].sort();\n}","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/itwanger/toBeBetterJavaer/blob/6617f5fd0b0597735bdc028f2fcd036817877327/scripts/convert-mdnice-images-to-cdn.js#L150-L186","documentation":"Thrown by validateOssConfig() in scripts/convert-mdnice-images-to-cdn.js before any network work when one or more of the five required OSS env vars (PAICODING_OSS_AK, PAICODING_OSS_SK, PAICODING_OSS_ENDPOINT, PAICODING_OSS_BUCKET, PAICODING_OSS_HOST) is missing or empty. The message lists exactly which keys are absent. The config is loaded from an env file (default .env at repo root, overridable with --env) merged with process.env.","triggerScenarios":"Running with --write before creating .env; pointing --env at a wrong path (loadEnv silently returns {} for a missing file, so no error until this check); .env exists but a key is misspelled (e.g. PAICODING_OSS_HOST_URL) or has an empty value; key present in .env but not exported when the vars were expected from the shell.","commonSituations":"Fresh clone without .env; CI runner secrets not wired; renaming the OSS provider; values commented out in .env; Windows line endings or `export ` prefixes that the simple line parser does not handle.","solutions":["Create .env in the repo root with all five keys listed in the error, then rerun","If your env file lives elsewhere, pass it explicitly: `--env=path/to/.env` (resolved relative to the repo root)","Verify with a dry run first — validation only fires for --write runs, so `node scripts/convert-mdnice-images-to-cdn.js` (no flags) confirms scanning works while you fix credentials"],"exampleFix":"# .env (repo root) — before: missing keys\nPAICODING_OSS_AK=...\n\n# after: all five required keys present\nPAICODING_OSS_AK=LTAI...\nPAICODING_OSS_SK=...\nPAICODING_OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com\nPAICODING_OSS_BUCKET=my-bucket\nPAICODING_OSS_HOST=https://cdn.example.com","handlingStrategy":"validation","validationCode":"// Pre-flight config check before invoking with --write\nconst REQUIRED = [\"PAICODING_OSS_AK\", \"PAICODING_OSS_SK\", \"PAICODING_OSS_ENDPOINT\", \"PAICODING_OSS_BUCKET\", \"PAICODING_OSS_HOST\"];\nconst missing = REQUIRED.filter((k) => !process.env[k] && !envFileHas(k));\nif (missing.length) { console.error(`Configure first: ${missing.join(\", \")}`); process.exit(2); }","typeGuard":"const hasOssConfig = (cfg) => [\"PAICODING_OSS_AK\",\"PAICODING_OSS_SK\",\"PAICODING_OSS_ENDPOINT\",\"PAICODING_OSS_BUCKET\",\"PAICODING_OSS_HOST\"].every((k) => Boolean(cfg[k]));","tryCatchPattern":"catch (err) { if (err.message.startsWith(\"Missing required env vars\")) { console.error(\"Create .env with the listed keys (see README); nothing was uploaded.\"); process.exit(2); } throw err; }","preventionTips":["Keep a .env.example committed listing the five PAICODING_OSS_* keys","Always do a dry run (omit --write) before the first --write run","Never print the secret values — check presence only"],"tags":["configuration","environment","oss","credentials"],"backgroundTag":null,"analyzedSha":"6617f5fd0b0597735bdc028f2fcd036817877327","analyzedAt":"2026-08-14T14:50:55.107Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}