What Happens When a Committed Model or Capability Disappears from Maka's Catalog

When a committed model or capability disappears from Maka's catalog, the Runtime Host treats it as a catalog-drift event: the missing entry is silently removed from the live catalog, sessions using it receive a catalog-unavailable flag, and the UI displays a graceful fallback while existing in-flight tasks continue with their captured snapshot.

Maka's model/capability catalog serves as the single source of truth for both the Runtime Host (the back-end execution engine) and the Desktop UI. Understanding how Maka handles disappearing committed models or capabilities is critical for building resilient AI applications that degrade gracefully when upstream provider catalogs change.

How Maka Detects a Missing Committed Entry

The detection process begins during the catalog refresh cycle. The Host periodically reloads the provider's catalog—or triggers an immediate reload after a save operation. When a previously known entry is absent from the refreshed data, Maka flags this as catalog drift.

In scripts/sync-model-metadata.mjs, the projection-building function detects vanished providers and logs a drift report. This occurs at line 292, where the sync script compares the incoming catalog against the persisted state.

// Conceptual flow from sync-model-metadata.mjs
// The actual detection happens during projection building
async function buildCatalogProjection(rawCatalog, persistedCatalog) {
  const driftReport = [];
  for (const [id, entry] of Object.entries(persistedCatalog)) {
    if (!rawCatalog[id]) {
      driftReport.push({ id, reason: 'vanished_from_provider' });
    }
  }
  return { projection: filteredCatalog, drift: driftReport };
}

Host-Side Validation and Committed State Updates

Once drift is detected, the Runtime Host validates the refreshed catalog against the persisted "committed" snapshot. Missing entries are pruned from the committed view, while diagnostics for the absent items are preserved for audit purposes.

The test suite in packages/runtime/src/__tests__/skills.test.ts confirms this behavior at line 127. Invalid—now missing—skills are excluded from the active catalog, yet their diagnostic records remain intact.

// Excerpt pattern from skills.test.ts demonstrating exclusion logic
describe('catalog validation', () => {
  it('excludes invalid skills while preserving diagnostics', () => {
    const committedSkills = loadCommittedSnapshot();
    const refreshedCatalog = syncWithProvider();
    
    const validSkills = refreshedCatalog.filter(s => committedSkills.has(s.id));
    const diagnostics = generateDriftReport(committedSkills, refreshedCatalog);
    
    expect(validSkills).not.toContainEqual(expect.objectContaining({ id: 'vanished-skill' }));
    expect(diagnostics.missing).toContain('vanished-skill');
  });
});

Session State and UI Degradation

Sessions that were using the now-missing model or capability receive a catalog-unavailable flag. UI components bound to the catalog—model pickers, capability selectors, and task configuration panels—render fallback states rather than crashing.

The test at apps/desktop/src/main/__tests__/task-submission-readiness-main.test.ts (line 43) asserts that the runtime is reported as closed when catalog resolution fails, preventing invalid task submissions.

// Pattern from task-submission-readiness-main.test.ts
it('reports runtime closed when catalog resolution fails', async () => {
  const readiness = await checkTaskSubmissionReadiness({
    modelId: 'vanished-model-123'
  });
  
  expect(readiness.canSubmit).toBe(false);
  expect(readiness.reason).toBe('catalog_unavailable');
});

Rendering the Unavailable State

The Desktop UI surface, specifically in components like those found in apps/desktop/src/renderer/settings/task-catalog-rows.ts, uses the catalog-unavailable flag to render empty states and warning messages. Users see clear feedback such as "No models are available" or "Capability unavailable" rather than broken interfaces.

Graceful Degradation for In-Flight Tasks

A critical resilience feature: if a task is already executing when the catalog changes, the Host continues using the snapshot captured at task start. This prevents mid-execution crashes due to catalog drift.

New tasks, however, must resolve against the refreshed catalog. Any submission referencing a missing entry is rejected at the validation boundary.

The runtime policy in packages/runtime-host/src/protocol/runtime-policy.ts (line 165) formalizes this ownership model: the Host maintains the authoritative catalog projection, and clients receive only the current validated view.

// Conceptual implementation matching runtime-policy.ts principles
class RuntimeHost {
  private catalogSnapshot: CatalogSnapshot;
  
  async startTask(taskRequest: TaskRequest): Promise<Task> {
    // New tasks validated against fresh catalog
    if (!this.currentCatalog.models[taskRequest.modelId]) {
      throw new CatalogResolutionError(`Model ${taskRequest.modelId} unavailable`);
    }
    
    // Capture snapshot for task lifetime
    const task = new Task(taskRequest, this.captureCatalogSnapshot());
    return task;
  }
  
  private captureCatalogSnapshot(): CatalogSnapshot {
    return structuredClone(this.currentCatalog);
  }
}

Client-Side Detection Patterns

Applications built on Maka can proactively detect missing entries using the runtime client.

Checking Model Availability

// -------------------------------------------------------------
// Load the current model catalog from the Runtime Host
// -------------------------------------------------------------
import { client } from '@maka/core/runtime-client';

async function getModelCatalog() {
  const catalog = await client.loadModelCatalog();
  return catalog; // { models: Record<string, ModelMetadata> }
}

// -------------------------------------------------------------
// Check whether a particular model ID is still present
// -------------------------------------------------------------
async function isModelAvailable(modelId: string): Promise<boolean> {
  const catalog = await getModelCatalog();
  return !!catalog.models?.[modelId];
}

React Component Integration

// -------------------------------------------------------------
// Example usage in a UI component
// -------------------------------------------------------------
import { useEffect, useState } from 'react';

function ModelStatus({ modelId }: { modelId: string }) {
  const [available, setAvailable] = useState(true);
  const [checking, setChecking] = useState(true);

  useEffect(() => {
    let cancelled = false;
    isModelAvailable(modelId)
      .then((ok) => {
        if (!cancelled) {
          setAvailable(ok);
          setChecking(false);
        }
      });
    return () => { cancelled = true; };
  }, [modelId]);

  if (checking) return <span>Verifying availability...</span>;
  if (!available) {
    return (
      <span style={{ color: 'red', fontWeight: 'bold' }}>
        ⚠️ Model no longer available — select an alternative
      </span>
    );
  }
  return <span>✓ Model is ready</span>;
}

Server-Side Submission Guard

// -------------------------------------------------------------
// Reject task submission if model missing
// -------------------------------------------------------------
import { RuntimeHost } from '@maka/runtime-host';

export async function submitTask(task: TaskRequest): Promise<Task> {
  const catalog = await RuntimeHost.loadModelCatalog();
  
  if (!catalog.models?.[task.modelId]) {
    throw new Error(
      `Cannot submit task – model "${task.modelId}" ` +
      `is not in the catalog. Available models: ${Object.keys(catalog.models).join(', ')}`
    );
  }
  
  return RuntimeHost.startTask(task);
}

Key Implementation Files

Understanding the full lifecycle requires familiarity with these source locations:

Summary

  • Catalog drift detection occurs during periodic or on-demand refresh cycles in the sync metadata script
  • Missing entries are pruned from the committed view while diagnostics are retained for audit purposes
  • Active sessions receive catalog-unavailable flags, triggering graceful UI fallback states
  • In-flight tasks use captured snapshots to prevent mid-execution failures
  • New task submissions are validated against the fresh catalog and rejected if referencing vanished entries
  • User experience remains stable through clear unavailable messaging rather than crashes or undefined behavior

Frequently Asked Questions

Does Maka crash if a committed model disappears while a task is running?

No. Maka's Runtime Host captures a catalog snapshot at task start and uses that snapshot for the task's entire lifetime. The catalog refresh and drift detection run independently. A task already in flight continues executing with its original model reference even if that model subsequently vanishes from the provider's catalog. New tasks, however, must resolve against the refreshed catalog.

How can my application detect that a model has become unavailable?

Query the runtime client's loadModelCatalog() method and verify that your target modelId exists in the returned models record. The boolean check !!catalog.models?.[modelId] provides a definitive availability signal. For reactive UIs, poll or subscribe to catalog updates and trigger re-renders when availability changes.

What happens to diagnostic data when a capability is removed?

Diagnostics are preserved even though the entry is excluded from the active catalog. The test suite in skills.test.ts explicitly verifies this behavior: the drift report captures what went missing and when, supporting audit trails and debugging, while the operational catalog remains clean of invalid references.

Can users still see removed models in the Maka Desktop interface?

No. The UI components in task-catalog-rows.ts and related renderers check the catalog-unavailable flag. Removed models do not appear in selectable lists. If a previously selected model vanishes while its configuration panel is open, the interface displays a warning such as "Model no longer available" and prompts the user to select an alternative.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →