Common issues and solutions for inference.sh apps.
Task stuck in Queued
Symptom: A run stays in Queued and never moves to Running.
Check:
- Cloud run — Usually resolves when a cloud worker is free. Heavy load or maintenance can add a short wait.
- Private run — Open Engines. The engine must be online and workers must match the app's GPU/CPU requirements. See Using private workers and Configuration.
- Resource mismatch — The app may require more VRAM or a specific GPU type than any connected worker provides.
- Infra mismatch — Some apps only allow cloud or only private; wrong
infrafails immediately instead of queuing.
Tasks wait in the queue for up to roughly 24 hours before failing with task expired while waiting for available capacity, please retry. If no worker matches the app's resource requirements at all, failure happens sooner (~10 minutes) with no active workers with matching resources. See Task status and Workers.
CLI: Use belt task get <id> -f to watch status until the task starts or fails. See CLI setup.
Platform task failures
Symptom: Task status is Failed with a short, generic error like task interrupted, please retry or task could not be dispatched, please retry.
Cause: The platform hit a transient infrastructure issue — worker disconnect, engine reconnect, dispatch retry exhaustion, or similar. These messages are intentionally user-friendly; internal diagnostics are not exposed in the error field.
What to do:
- Retry the run — most platform failures are transient.
- Check task logs — app-level errors (validation, OOM, model failures) appear with your app's own message and are not sanitized.
- Session runs — if you see
session worker busy too long, wait for the prior call on that session to finish or serialize session calls. See Sessions — Task failures. - Secrets —
failed to prepare secrets for this app, please check your secret configurationmeans a required team secret is missing or invalid. Add or fix secrets in Settings → Secrets.
For the full list of platform error strings, see Task failure messages.
CLI billing or plan limit errors
Symptom: belt or infsh prints a message about insufficient balance, upgrading your plan, or a link to billing settings.
Cause: The API returned 402 Payment Required (credits) or 403 Forbidden with an entitlement error (upgrade_available in the error metadata).
What to do:
- Insufficient balance — Add credits at Settings → Billing. The CLI includes the billing URL in the error message.
- Plan limit — Upgrade at Settings → Subscription when the error mentions upgrading your plan.
- Not logged in — Run
belt login(orinfsh login) if you see "not logged in or session expired".
These messages come from the API error body; with X-API-Version: 2, other failures use RFC 9457 problem+json instead of the legacy { "error": { ... } } shape.
Tasks rejected during engine maintenance
Symptom: New private tasks fail immediately or stay queued while you update or drain an engine.
Cause: While an engine is draining (or receiving an update), it rejects new work with reason engine_draining until in-flight tasks finish and the engine restarts.
What to do:
- Wait for running tasks on that engine to complete, or cancel them if you need a faster turnaround.
- Use Drain before maintenance and Update when you want a safe binary upgrade — see Engines API.
- Route urgent work to cloud infra or another online engine with
infra: "cloud"or a different private engine.
Plan limits and billing errors
Symptom: API or CLI calls fail with HTTP 402 or 403, or messages about limits, balance, or upgrading your plan.
Plan usage limit (limit_exceeded, HTTP 402)
You hit a subscription limit — for example too many API keys, connectors, knowledge bases, private apps, or storage.
What to do:
- In the workspace, the app opens an upgrade modal with a recommended plan — the cheapest tier that lifts the blocked limit. It shows current usage vs your cap when the cap is greater than zero.
- Open Settings → Subscription to compare all plans and change your subscription.
- Delete or reduce usage (unused API keys, old knowledge entries, large files).
- Inspect limits programmatically:
GET /entitlementsfor limits andGET /entitlements/usagefor current counts — see Entitlements API.
Feature not on your tier (feature_not_available, HTTP 403)
The operation requires a capability your plan does not include (for example feature:publish_apps or feature:webhooks).
The workspace upgrade modal lists higher tiers and recommends the cheapest plan that enables the feature. Upgrade at Settings → Subscription or contact support if you believe the feature should already be enabled.
Insufficient balance (payment_required, HTTP 402)
Task and agent runs charge prepaid credits. When balance is too low, POST /run and agent message endpoints return payment_required.
Add credits at Settings → Billing.
CLI messages
The belt / infsh CLI sends X-API-Version: 2 and prints the API detail message for most errors. For HTTP 402 without a parsed entitlement body, the CLI may suggest the billing URL for credits — check whether the failure is a plan limit (entitlements) or balance (credits).
→ REST overview — Billing and plan limits · Entitlements API
Import Errors
"ModuleNotFoundError" in Production
Solutions:
-
Add
__init__.pyfiles to all packages -
Add current directory to Python path:
1import sys, os2sys.path.append(os.path.dirname(os.path.abspath(__file__)))- For local packages, use editable installs:
1-e ./local_package_directoryMemory Issues
"CUDA out of memory"
Solutions:
- Reduce batch size
- Use mixed precision:
model.to(dtype=torch.float16) - Enable gradient checkpointing:
model.gradient_checkpointing_enable() - Clear cache:
torch.cuda.empty_cache() - Increase VRAM in
inf.yml
Memory Leaks
Clean up after each request:
1import gc, torch23async def run(self, input_data):4 result = self.process(input_data)5 if torch.cuda.is_available():6 torch.cuda.empty_cache()7 gc.collect()8 return resultDevice Errors
"Expected all tensors to be on the same device"
Ensure all tensors are on the same device:
1input_tensor = input_tensor.to(self.device)"CUDA not available"
- Check
inf.ymlGPU requirements:
1resources:2 gpu:3 count: 14 vram: 24 # 24GB- Use device detection:
1from accelerate import Accelerator2device = Accelerator().deviceModel Loading Errors
"File not found" After Download
Don't assume file paths:
1model_path = snapshot_download(repo_id="org/model")2config_path = os.path.join(model_path, "config.yaml")3if os.path.exists(config_path):4 # Load config"Token required for gated model"
Add HF_TOKEN to secrets:
1secrets:2 - key: HF_TOKEN3 description: HuggingFace token for gated modelsFile Path Issues
Temporary Files Deleted Too Early
Use delete=False:
1with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as tmp:2 output_path = tmp.namePath Separators
Use os.path.join:
1# ✅ Good2path = os.path.join("models", "config", "settings.json")Dependency Issues
Version Conflicts
Pin compatible versions:
1torch==2.6.02numpy>=1.23.5,<2Flash Attention Build Errors
Use pre-built wheels in requirements2.txt
Debug Mode
Add logging:
1import logging2logging.basicConfig(level=logging.DEBUG)34async def setup(self, config):5 logging.debug(f"Config: {config}")6 logging.info("Starting model load...")Node.js-Specific Issues
"ERR_MODULE_NOT_FOUND"
Ensure "type": "module" is in your package.json and use file extensions in imports:
1import { helper } from "./helper.js"; // .js required for ESM"Cannot use import statement outside a module"
Your package.json must have:
1{2 "type": "module"3}Native Module Build Errors
Some packages (e.g., sharp, canvas) need system libraries. Add them to packages.txt:
1libvips-devClaude Code belt plugin issues
Symptom: Hooks stop running, belt suggest never appears in context, or Claude Code reports that the plugin directory does not exist.
Check:
1belt plugin doctorThe doctor verifies belt CLI availability, authentication (not guest), the belt entry in Claude's installed_plugins.json, that the install path exists, that hooks/hooks.json is present, that hook scripts in bin/ use the thin shim pattern (exec belt plugin hook <event>) across Claude and Codex plugin caches, and recent hook activity in ~/.belt/hooks.log.
Fix:
1belt plugin doctor --fix--fix reinstalls the belt plugin when the cache path is stale or missing (claude plugin uninstall belt@belt-sh-skills, then claude plugin install belt, with marketplace add as fallback), removes other stale cache directories under the plugin install parent, and patches hook scripts that still contain embedded logic instead of the thin shim format (exec belt plugin hook <event>). The same hook patching runs automatically after belt plugin init claude because marketplace caching can serve stale hook scripts. For auth issues it prints belt login guidance (guest sessions disable knowledge persistence).
When all checks pass, doctor prints All checks passed. When --fix applies repairs, it lists each change (for example fixed: removed stale cache dir abc123, fixed: reinstalled plugin (cache path was stale), or fixed: patched hook-stop.sh in <hash>), then prompts you to restart. Inside a Claude Code session, doctor suggests Run /reload-plugins or restart this session to apply changes; from a regular terminal, it suggests Restart your agent session to apply changes.
→ Claude Code plugin · CLI setup — Agent integration
CLI billing and authentication errors
Symptom: belt or infsh fails with a message about balance, plan limits, or login.
| Message | What to do |
|---|---|
insufficient balance + billing URL | Add credits at Billing |
upgrade your plan + subscription URL | Raise plan limits at Subscription |
not logged in or session expired | Run belt login (or infsh login) |
See CLI setup — Billing and plan limits for details.
Next
→ Best Practices - Optimization patterns