{"record":{"id":"9060d962eb973d07","repo":"santifer/career-ops","slug":"h1b-api-base-is-set-but-empty-unset-it-to-use-the","errorCode":null,"errorMessage":"H1B_API_BASE is set but empty. Unset it to use the default endpoint.","messagePattern":"H1B_API_BASE is set but empty\\. Unset it to use the default endpoint\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/h1b-sponsor/lib/api.mjs","lineNumber":43,"sourceCode":"let resolvedBase;\n\nexport function apiBase() {\n  // Only a successful resolve is memoized; a bad value keeps throwing so the\n  // failure cannot be masked by an earlier call that happened to succeed.\n  if (resolvedBase === undefined) resolvedBase = resolveBase();\n  return resolvedBase;\n}\n\nfunction resolveBase() {\n  const raw = process.env.H1B_API_BASE;\n  // Absent means \"use the default\". Present but blank is a misconfiguration\n  // (an unset shell variable, an empty .env line, a CI secret that did not\n  // populate), and silently falling back would send someone's shortlist and\n  // their token to a host they believed they had replaced.\n  if (raw === undefined) return DEFAULT_BASE;\n  const trimmed = String(raw).trim();\n  if (!trimmed) {\n    throw new Error('H1B_API_BASE is set but empty. Unset it to use the default endpoint.');\n  }\n\n  let parsed;\n  try {\n    parsed = new URL(trimmed);\n  } catch {\n    throw new Error(`H1B_API_BASE is not a valid URL: ${trimmed}`);\n  }\n  if (parsed.username || parsed.password) {\n    // Undici refuses a credentialed Request anyway, and the value reaches\n    // stdout through the source field, so this would print a password.\n    throw new Error('H1B_API_BASE must not embed credentials.');\n  }\n  if (parsed.search || parsed.hash) {\n    // Paths are appended, so a query or fragment swallows them: the request\n    // would go to the base itself and answer about a company never asked for.\n    throw new Error('H1B_API_BASE must not contain a query string or a fragment.');\n  }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/santifer/career-ops/blob/1696bec4d021768e7359f9aad6b329cba883da20/plugins/h1b-sponsor/lib/api.mjs#L25-L61","documentation":"resolveBase() reads the H1B_API_BASE environment variable to allow replacing the default API endpoint. An unset variable falls back to DEFAULT_BASE, but a variable that is set to an empty/whitespace-only string is rejected: the comment explains that silently falling back could send someone's shortlist and token to a host they believed they had replaced — i.e. an empty value most likely means an override failed to populate, and guessing would be dangerous.","triggerScenarios":"resolveBase() is called during plugin init/API client construction while process.env.H1B_API_BASE is defined (present in the environment, .env file, or CI secret store) but trims to an empty string; raw !== undefined but !trimmed.","commonSituations":"A .env line like 'H1B_API_BASE=' left behind after removing a value; a CI/CD secret (GitHub Actions secret, Docker env) referenced but never populated, injecting an empty string; a shell script doing H1B_API_BASE= instead of unset H1B_API_BASE; a compose/k8s env entry with a missing ConfigMap value.","solutions":["Unset the variable entirely (unset H1B_API_BASE / delete the .env line) so the default endpoint is used.","If you meant to override the endpoint, set it to the full URL, e.g. export H1B_API_BASE=https://your-host.example.com.","In CI, fix the secret/variable reference so it actually populates, or remove the env entry.","Grep your .env, shell rc, and deployment manifests for 'H1B_API_BASE=' with no value."],"exampleFix":"// before (.env)\nH1B_API_BASE=\n// after (.env)\nH1B_API_BASE=https://h1b-api.internal.example.com\n// or simply remove the line to use the default endpoint","handlingStrategy":"validation","validationCode":"const raw = process.env.H1B_API_BASE;\nif (raw !== undefined && !raw.trim()) {\n  throw new Error('H1B_API_BASE is set but empty — unset it (unset H1B_API_BASE) or set a full URL');\n}","typeGuard":"function hasValidBaseOverride(env = process.env) {\n  const raw = env.H1B_API_BASE;\n  if (raw === undefined) return true; // default endpoint\n  if (!String(raw).trim()) return false;\n  try { new URL(String(raw).trim()); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await installH1BIndex();\n} catch (e) {\n  if (String(e.message).includes('H1B_API_BASE is set but empty')) {\n    console.error('Fix your environment: either unset H1B_API_BASE or provide a full https:// URL.');\n  } else throw e;\n}","preventionTips":["Prefer unset over setting an empty string in .env files and shell scripts.","In CI, verify the secret actually populates before jobs that call the plugin.","Grep .env / rc files / manifests for 'H1B_API_BASE=' with no value during setup.","Validate env overrides at script startup so failures surface before any install runs."],"tags":["configuration","environment","env-var"],"backgroundTag":"missing-env-var","analyzedSha":"1696bec4d021768e7359f9aad6b329cba883da20","analyzedAt":"2026-09-01T19:19:23.111Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}