{"record":{"id":"9c92a2e7dd4d4506","repo":"vercel/ai","slug":"maxembeddingspercall-must-be-greater-than-0","errorCode":null,"errorMessage":"maxEmbeddingsPerCall must be greater than 0","messagePattern":"maxEmbeddingsPerCall must be greater than 0","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ai/src/embed/embed-many.ts","lineNumber":451,"sourceCode":"        throw error;\n      }\n    },\n  });\n}\n\nconst textEncoder = new TextEncoder();\n\nfunction splitByEmbeddingLimits({\n  values,\n  maxEmbeddingsPerCall,\n  maxInputBytesPerCall,\n}: {\n  values: Array<string>;\n  maxEmbeddingsPerCall: number;\n  maxInputBytesPerCall: number;\n}): Array<Array<string>> {\n  if (maxEmbeddingsPerCall <= 0) {\n    throw new Error('maxEmbeddingsPerCall must be greater than 0');\n  }\n\n  if (maxInputBytesPerCall <= 0) {\n    throw new Error('maxInputBytesPerCall must be greater than 0');\n  }\n\n  if (values.length === 0) {\n    return [];\n  }\n\n  const chunks: Array<Array<string>> = [];\n  let currentChunk: Array<string> = [];\n  let currentInputBytes = 0;\n\n  for (const value of values) {\n    const inputBytes = textEncoder.encode(value).length;\n\n    if (","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/ai/src/embed/embed-many.ts#L433-L469","documentation":"validateACPSkills (run by materializeACPSkills before writing any files) requires every skill name to match /^[a-z0-9]+(?:-[a-z0-9]+)*$/ — a lowercase kebab-case slug — and not be '.' or '..'. Names with uppercase letters, underscores, spaces, or empty strings are rejected because skill names become directory names on disk.","triggerScenarios":"Providing a HarnessV1Skill whose name is 'My Skill', 'my_skill', 'MySkill', '', '.', '..', or contains non-ASCII characters when passing skills to the ACP harness.","commonSituations":"Generating skill names from display names or titles; converting folder names with underscores to skills; user-authored skill configs that were never slugified.","solutions":["Slugify the name to lowercase kebab-case: lowercase, replace underscores/spaces with '-', strip invalid characters.","Collapse consecutive dashes and trim leading/trailing dashes.","Validate all skill names with the kebab-case regex before submitting skills."],"exampleFix":"// before\n{ name: 'Code Reviewer', files: [...] }\n\n// after\n{ name: 'code-reviewer', files: [...] }","handlingStrategy":"validation","validationCode":"const KEBAB = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nfunction slugify(name: string): string {\n  return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');\n}\nskills.forEach(s => { if (!KEBAB.test(s.name)) s.name = slugify(s.name) || 'skill'; });","typeGuard":"function isKebabCaseSlug(name: string): boolean {\n  return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name) && name !== '.' && name !== '..';\n}","tryCatchPattern":"try {\n  await agent.addSkills(skills);\n} catch (error) {\n  if (error instanceof Error && error.message.includes('expected a kebab-case slug')) {\n    await agent.addSkills(skills.map(s => ({ ...s, name: slugify(s.name) })));\n  } else {\n    throw error;\n  }\n}","preventionTips":["Slugify display names at the point where skills are authored or loaded.","Add a unit test that asserts all skill names match the kebab-case regex.","Ban spaces and underscores in skill naming conventions/documentation."],"tags":["acp","validation","naming","skills"],"backgroundTag":"invalid-slug","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}