{"record":{"id":"42a74608cd081351","repo":"janhq/jan","slug":"model-yml-not-found-for-modelid","errorCode":null,"errorMessage":"model.yml not found for ${modelId}","messagePattern":"model\\.yml not found for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":3904,"sourceCode":"  }\n\n  async updateMtpSettings(\n    modelId: string,\n    patch: {\n      mtp?: boolean\n      spec_draft_n_max?: number | null\n      spec_draft_n_min?: number | null\n      spec_draft_p_min?: number | null\n    }\n  ): Promise<void> {\n    const configPath = await joinPath([\n      await this.getProviderPath(),\n      'models',\n      modelId,\n      'model.yml',\n    ])\n    if (!(await fs.existsSync(configPath))) {\n      throw new Error(`model.yml not found for ${modelId}`)\n    }\n    const cfg = (await invoke<ModelConfig>('read_yaml', { path: configPath })) as ModelConfig & {\n      mtp?: boolean\n      spec_draft_n_max?: number\n      spec_draft_n_min?: number\n      spec_draft_p_min?: number\n    }\n\n    if (typeof patch.mtp === 'boolean') cfg.mtp = patch.mtp\n    const assignNumeric = (\n      key: 'spec_draft_n_max' | 'spec_draft_n_min' | 'spec_draft_p_min',\n      value: number | null | undefined\n    ) => {\n      if (value === null) {\n        delete cfg[key]\n      } else if (typeof value === 'number' && Number.isFinite(value)) {\n        cfg[key] = value\n      }","sourceCodeStart":3886,"sourceCodeEnd":3922,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/llamacpp-extension/src/index.ts#L3886-L3922","documentation":"Thrown by updateMtpSettings() when <provider>/models/<modelId>/model.yml does not exist. The method patches MTP/speculative-decoding fields onto the existing config and re-writes it; without model.yml there is nothing to read or patch. The same guard exists in updateModelSettings() (line 3958) and is the canonical precondition for any per-model config write.","triggerScenarios":"Calling updateMtpSettings on an id that was never imported or was deleted; the model folder exists but model.yml is missing (corrupt/partial import); wrong id (typo/case); calling it before import() has finished writing model.yml.","commonSituations":"UI lets the user open MTP settings for a model still downloading (model.yml not yet written). Migrating models by copying weight files but forgetting model.yml. Race: import failed validation but the UI still shows the row. Case-insensitive FS id mismatch.","solutions":["Ensure the model is fully imported (import() resolved, model.yml on disk) before updating MTP settings.","Pre-check fs.existsSync(configPath) and disable the MTP controls in the UI until it exists.","If model.yml was lost, re-import the model.","Verify the modelId casing/spelling matches the imported id."],"exampleFix":"// before\nawait provider.updateMtpSettings('qwen', { mtp: true }) // throws - not imported yet\n// after - gate on import completion\nconst yml = await joinPath([await provider.getProviderPath(), 'models', 'qwen', 'model.yml'])\nif (!(await fs.existsSync(yml))) { throw new Error('model not fully imported yet') }\nawait provider.updateMtpSettings('qwen', { mtp: true })","handlingStrategy":"validation","validationCode":"// Ensure model.yml exists before patching MTP settings\nconst yml = await joinPath([await provider.getProviderPath(), 'models', modelId, 'model.yml'])\nif (!(await fs.existsSync(yml))) {\n  throw new Error(`Cannot update MTP settings: '${modelId}' is not fully imported (model.yml missing)`)\n}","typeGuard":"async function modelConfigExists(provider: { getProviderPath(): Promise<string> }, id: string): Promise<boolean> {\n  const yml = await joinPath([await provider.getProviderPath(), 'models', id, 'model.yml'])\n  return fs.existsSync(yml)\n}","tryCatchPattern":"try { await provider.updateMtpSettings(modelId, patch) }\ncatch (e) {\n  if (/model\\.yml not found/.test(String(e))) { /* disable MTP UI until import finishes */ }\n  else throw e\n}","preventionTips":["Disable MTP/settings controls in the UI until import() has resolved and model.yml is written.","Gate any per-model config write on the existence of model.yml at the caller.","Re-import the model if model.yml was lost."],"tags":["model","mtp","config","filesystem","validation","settings"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}