{"record":{"id":"437239c4e106b95e","repo":"eythaann/Seelen-UI","slug":"no-key-provided-to-t","errorCode":null,"errorMessage":"no key provided to $t()","messagePattern":"no key provided to \\$t\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"libs/ui/svelte/utils/i18n.svelte.ts","lineNumber":9,"sourceCode":"import yaml from \"js-yaml\";\n\nlet _locale = $state(\"en\");\nlet _messages = $state.raw<Record<string, any>>({});\n\nfunction translate(locale: string, key: string, vars: Record<string, string> = {}) {\n  // Let's throw some errors if we're trying to use keys/locales that don't exist.\n  // We could improve this by using Typescript and/or fallback values.\n  if (!key) throw new Error(\"no key provided to $t()\");\n  if (!locale) throw new Error(`no translation for key \"${key}\"`);\n\n  // Grab the translation from the translations object.\n  // Support nested keys like \"profile.log_out\"\n  const keys = key.split(\".\");\n  let text = _messages[locale];\n\n  for (const k of keys) {\n    text = text?.[k];\n  }\n\n  if (!text) {\n    console.error(`no translation found for ${locale}.${key}`);\n    // Try fallback to English\n    let fallback = _messages[\"en\"];\n    for (const k of keys) {\n      fallback = fallback?.[k];\n    }","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/eythaann/Seelen-UI/blob/dee4aaa94066c5d0888ab25554864862fc47be15/libs/ui/svelte/utils/i18n.svelte.ts#L1-L27","documentation":"The internal translate() function backing the $t() helper validates its inputs: a falsy (empty/undefined/null) key cannot be looked up in the messages table, so it throws immediately with 'no key provided to $t()'. This is a programming-mistake guard rather than a data problem — the key string itself is missing.","triggerScenarios":"Calling t('') or t(undefined); passing a variable that is undefined because the constant/import is missing; building keys dynamically (t(`app.${section}`)) where section is undefined; passing arguments in the wrong order so the key slot receives the wrong value.","commonSituations":"Renaming a key constant and leaving a call site undefined; optional chaining producing undefined keys (t(obj?.key)); template-literal keys built from not-yet-loaded data; copy-pasted t() calls with arguments dropped.","solutions":["Pass a non-empty key string to t(); audit the call site for undefined variables.","Type keys as a union of known keys (or derive from the translations object) so missing keys fail at compile time.","For dynamic keys, default them: t(`app.${section ?? 'default'}`).","Add a dev-time assertion/log before t() when keys are computed."],"exampleFix":"// before: const key = config.translationKey; /* undefined */ t(key);\n// after: if (config.translationKey) t(config.translationKey);","handlingStrategy":"validation","validationCode":"function safeT(key?: string, vars?: Record<string, string>) { if (!key) return key ?? ''; return t(key, vars); }","typeGuard":"function isTranslationKey(key: unknown): key is string { return typeof key === 'string' && key.length > 0; }","tryCatchPattern":"try { label = $t(key); } catch (e) { if (e instanceof Error && e.message.includes('no key provided')) { label = key ?? ''; } else { throw e; } }","preventionTips":["Type keys as a union derived from the translations object so missing keys fail at compile time.","Never build keys from possibly-undefined data without a default.","Avoid optional-chained values as keys.","Lint/grep for t() calls with empty or dynamic-unchecked arguments."],"tags":["i18n","validation","arguments"],"backgroundTag":"missing-i18n-key","analyzedSha":"dee4aaa94066c5d0888ab25554864862fc47be15","analyzedAt":"2026-09-03T10:20:37.842Z","contentChangedAt":"2026-09-03T10:20:37.842Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}