{"record":{"id":"aece9b36e69b4a43","repo":"tobi/qmd","slug":"handelize-path-path-has-no-valid-filename-co","errorCode":null,"errorMessage":"handelize: path \"${path}\" has no valid filename content","messagePattern":"handelize: path \"(.+?)\" has no valid filename content","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/store.ts","lineNumber":2375,"sourceCode":"    // Split the run into individual emoji and convert each to hex, dash-separated\n    return [...run].filter(c => /\\p{So}|\\p{Sk}/u.test(c))\n      .map(c => c.codePointAt(0)!.toString(16)).join('-');\n  });\n}\n\nexport function handelize(path: string): string {\n  if (!path || path.trim() === '') {\n    throw new Error('handelize: path cannot be empty');\n  }\n\n  // Allow route-style \"$\" filenames while still rejecting paths with no usable content.\n  // Emoji (\\p{So}) counts as valid content — they get converted to hex codepoints below.\n  const segments = path.split('/').filter(Boolean);\n  const lastSegment = segments[segments.length - 1] || '';\n  const filenameWithoutExt = lastSegment.replace(/\\.[^.]+$/, '');\n  const hasValidContent = /[\\p{L}\\p{N}\\p{So}\\p{Sk}$]/u.test(filenameWithoutExt);\n  if (!hasValidContent) {\n    throw new Error(`handelize: path \"${path}\" has no valid filename content`);\n  }\n\n  const result = path\n    .replace(/___/g, '/')       // Triple underscore becomes folder separator\n    .split('/')\n    .map((segment, idx, arr) => {\n      const isLastSegment = idx === arr.length - 1;\n\n      // Convert emoji to hex codepoints before cleaning\n      segment = emojiToHex(segment);\n\n      if (isLastSegment) {\n        // For the filename (last segment), preserve the extension\n        const extMatch = segment.match(/(\\.[a-z0-9]+)$/i);\n        const ext = extMatch ? extMatch[1] : '';\n        const nameWithoutExt = ext ? segment.slice(0, -ext.length) : segment;\n\n        const cleanedName = nameWithoutExt","sourceCodeStart":2357,"sourceCodeEnd":2393,"githubUrl":"https://github.com/tobi/qmd/blob/dbfd0b4736aeaf761d1a16ca8e424f071df8feb9/src/store.ts#L2357-L2393","documentation":"After splitting the path and stripping the extension, the remaining filename contains no letters, numbers, symbols (\\p{So}/\\p{Sk}), or '$' — i.e. only punctuation like dots, dashes, underscores — so no valid handle can be produced.","triggerScenarios":"Calling handelize on a path whose basename is all punctuation, e.g. handelize('docs/-.md') or handelize('...') — the filenameWithoutExt fails the /[\\p{L}\\p{N}\\p{So}\\p{Sk}$]/u test.","commonSituations":"Temp or system files named '-', '...', or '._.' being indexed; glob patterns matching dotfiles without meaningful names; sanitization upstream stripping all alphanumerics.","solutions":["Skip such files during indexing (filter before handelize)","Rename the file to include at least one letter/number","Pre-check the basename with the same regex before calling"],"exampleFix":"// before\nconst h = handelize(p); // p = 'tmp/-.md'\n// after\nconst VALID = /[\\p{L}\\p{N}\\p{So}\\p{Sk}$]/u;\nconst base = p.split('/').filter(Boolean).pop()?.replace(/\\.[^.]+$/, '') ?? '';\nconst h = VALID.test(base) ? handelize(p) : null;","handlingStrategy":"validation","validationCode":"const VALID = /[\\p{L}\\p{N}\\p{So}\\p{Sk}$]/u;\nconst base = p.split('/').filter(Boolean).pop()?.replace(/\\.[^.]+$/, '') ?? '';\nif (VALID.test(base)) handelize(p); else skip();","typeGuard":"const hasHandleContent = (p: string) => /[\\p{L}\\p{N}\\p{So}\\p{Sk}$]/u.test((p.split('/').filter(Boolean).pop() || '').replace(/\\.[^.]+$/, ''));","tryCatchPattern":null,"preventionTips":["Filter punctuation-only filenames in indexing masks","Exclude system temp files (-, ...) from globs","Rename files without alphanumerics"],"tags":["path","filename","validation","unicode"],"backgroundTag":"invalid-filename","analyzedSha":"dbfd0b4736aeaf761d1a16ca8e424f071df8feb9","analyzedAt":"2026-08-28T18:07:46.628Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}