Agent skill

railway-doctor

Stars 0
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/stars-end/agent-skills/tree/master/railway-doctor

SKILL.md

railway-doctor

Description

Pre-flight checks for Railway deployments to catch failures BEFORE deploying.

Use when:

  • About to deploy to Railway ("deploy to railway", "railway up")
  • Railway deployment fails (imports break, env issues, lockfile errors)
  • Debugging Railway 500 errors
  • User says "check railway", "railway pre-flight", "why did railway fail"

Problem solved: Eliminates "Deploy to Railway β†’ Imports break β†’ Iterate" pattern (12/69 toil commits, 17% of analyzed toil).

Auto-Activation

This skill activates when:

  • User mentions Railway deployment ("railway", "deploy", "railway up")
  • CI deployment step fails
  • Railway shows 500 errors or build failures
  • Before important deployments (staging, production)

Implementation

The skill performs comprehensive pre-flight checks to catch Railway deployment issues early.

Check Script

bash
#!/bin/bash
# ~/.agent/skills/railway-doctor/check.sh

set -e

echo "πŸš‚ Railway Doctor - Pre-flight Check"

ISSUES_FOUND=0

# Check 1: Critical Python imports (Backend)
if [[ -f "backend/pyproject.toml" ]]; then
  echo ""
  echo "🐍 Checking Python imports (backend)..."
  cd backend

  # Ensure poetry env exists
  if ! poetry env info &>/dev/null; then
    echo "Installing Poetry environment..."
    poetry install --no-root
  fi

  # Test critical imports
  if poetry run python -c "
import sys
from pathlib import Path
sys.path.insert(0, str(Path.cwd()))

# Test critical imports that commonly break in Railway
try:
    from services.plaid_adapter import PlaidAdapter
    from brokers.security_resolver import SecurityResolver
    from api.routers import health
    print('βœ… All critical imports valid')
except ImportError as e:
    print(f'❌ Import will fail in Railway: {e}')
    sys.exit(1)
" 2>&1; then
    echo "βœ… Backend imports validated"
  else
    echo "❌ ERROR: Backend imports will fail in Railway"
    echo "   Fix import paths or missing dependencies"
    ISSUES_FOUND=$((ISSUES_FOUND + 1))
  fi

  cd ..
fi

# Check 2: Lockfiles in sync
echo ""
echo "πŸ“¦ Checking lockfiles..."

# Poetry lockfile
if [[ -f "backend/pyproject.toml" ]]; then
  cd backend
  if poetry check --lock 2>/dev/null; then
    echo "βœ… backend/poetry.lock in sync"
  else
    echo "❌ ERROR: backend/poetry.lock out of sync"
    echo "   Run: cd backend && poetry lock --no-update"
    ISSUES_FOUND=$((ISSUES_FOUND + 1))
  fi
  cd ..
elif [[ -f "pyproject.toml" ]]; then
  if poetry check --lock 2>/dev/null; then
    echo "βœ… poetry.lock in sync"
  else
    echo "❌ ERROR: poetry.lock out of sync"
    echo "   Run: poetry lock --no-update"
    ISSUES_FOUND=$((ISSUES_FOUND + 1))
  fi
fi

# pnpm lockfile
if [[ -f "frontend/package.json" ]]; then
  cd frontend
  if pnpm install --frozen-lockfile 2>/dev/null; then
    echo "βœ… frontend/pnpm-lock.yaml in sync"
  else
    echo "❌ ERROR: frontend/pnpm-lock.yaml out of sync"
    echo "   Run: cd frontend && pnpm install"
    ISSUES_FOUND=$((ISSUES_FOUND + 1))
  fi
  cd ..
elif [[ -f "package.json" ]]; then
  if pnpm install --frozen-lockfile 2>/dev/null; then
    echo "βœ… pnpm-lock.yaml in sync"
  else
    echo "❌ ERROR: pnpm-lock.yaml out of sync"
    echo "   Run: pnpm install"
    ISSUES_FOUND=$((ISSUES_FOUND + 1))
  fi
fi

# Check 3: Required environment variables (if Railway CLI available)
if command -v railway &>/dev/null; then
  echo ""
  echo "πŸ”‘ Checking Railway environment variables..."

  REQUIRED_VARS=(
    "DATABASE_URL"
    "SUPABASE_URL"
    "CLERK_SECRET_KEY"
  )

  for VAR in "${REQUIRED_VARS[@]}"; do
    if railway variables 2>/dev/null | grep -q "^$VAR"; then
      echo "βœ… $VAR set"
    else
      echo "⚠️  WARNING: $VAR not set in Railway environment"
      echo "   Set via: railway variables set $VAR=<value>"
      ISSUES_FOUND=$((ISSUES_FOUND + 1))
    fi
  done
else
  echo ""
  echo "ℹ️  Railway CLI not installed (skipping env var check)"
  echo "   Install: npm install -g @railway/cli"
fi

# Check 4: Railway configuration file
echo ""
echo "βš™οΈ  Checking Railway configuration..."

if [[ -f "railway.toml" ]] || [[ -f "railway.json" ]]; then
  echo "βœ… Railway config file found"
else
  echo "⚠️  No railway.toml or railway.json found"
  echo "   Consider adding for build configuration"
fi

echo ""
echo "═══════════════════════════════════════"
if [[ $ISSUES_FOUND -eq 0 ]]; then
  echo "βœ… All pre-flight checks passed!"
  echo "   Safe to deploy to Railway"
  exit 0
else
  echo "❌ Found $ISSUES_FOUND issue(s) - deployment will likely fail"
  echo ""
  echo "Fix issues before deploying to Railway"
  exit 1
fi

Fix Script

bash
#!/bin/bash
# ~/.agent/skills/railway-doctor/fix.sh

set -e

echo "πŸ”§ Railway Doctor - Fixing issues..."

FIXED=0

# Fix 1: Regenerate lockfiles
echo ""
echo "πŸ“¦ Fixing lockfiles..."

# Poetry
if [[ -f "backend/pyproject.toml" ]]; then
  cd backend
  if ! poetry check --lock 2>/dev/null; then
    echo "Regenerating backend/poetry.lock..."
    poetry lock --no-update
    git add poetry.lock
    echo "βœ… backend/poetry.lock fixed"
    FIXED=$((FIXED + 1))
  fi
  cd ..
elif [[ -f "pyproject.toml" ]]; then
  if ! poetry check --lock 2>/dev/null; then
    echo "Regenerating poetry.lock..."
    poetry lock --no-update
    git add poetry.lock
    echo "βœ… poetry.lock fixed"
    FIXED=$((FIXED + 1))
  fi
fi

# pnpm
if [[ -f "frontend/package.json" ]]; then
  cd frontend
  if ! pnpm install --frozen-lockfile 2>/dev/null; then
    echo "Regenerating frontend/pnpm-lock.yaml..."
    pnpm install
    git add pnpm-lock.yaml
    echo "βœ… frontend/pnpm-lock.yaml fixed"
    FIXED=$((FIXED + 1))
  fi
  cd ..
elif [[ -f "package.json" ]]; then
  if ! pnpm install --frozen-lockfile 2>/dev/null; then
    echo "Regenerating pnpm-lock.yaml..."
    pnpm install
    git add pnpm-lock.yaml
    echo "βœ… pnpm-lock.yaml fixed"
    FIXED=$((FIXED + 1))
  fi
fi

# Fix 2: Import issues - can't auto-fix, only provide guidance
if [[ -f "backend/pyproject.toml" ]]; then
  cd backend
  if ! poetry run python -c "
import sys
from pathlib import Path
sys.path.insert(0, str(Path.cwd()))
from services.plaid_adapter import PlaidAdapter
" 2>/dev/null; then
    echo ""
    echo "⚠️  Cannot auto-fix: Import errors detected"
    echo "   Manual fixes needed:"
    echo "   - Check import paths in Railway match local"
    echo "   - Verify all dependencies in pyproject.toml"
    echo "   - Test with: cd backend && poetry run python -c 'from services.plaid_adapter import PlaidAdapter'"
  fi
  cd ..
fi

# Fix 3: Environment variables - can't auto-fix, only guide
if command -v railway &>/dev/null; then
  echo ""
  echo "⚠️  Environment variable issues require manual setup in Railway dashboard"
  echo "   Or use: railway variables set VARIABLE_NAME=value"
fi

echo ""
echo "═══════════════════════════════════════"
if [[ $FIXED -eq 0 ]]; then
  echo "ℹ️  No auto-fixable issues found"
  echo "   Check error messages above for manual fixes"
else
  echo "βœ… Fixed $FIXED issue(s)"
  echo ""
  echo "Re-run railway-doctor check to verify all issues resolved"
fi

Usage Examples

Pre-flight check before deployment

bash
railway-doctor check

Auto-fix lockfile issues

bash
railway-doctor fix

CI Integration

yaml
# .github/workflows/deploy.yml
- name: Railway Pre-flight Check
  run: ~/.agent/skills/railway-doctor/check.sh

- name: Deploy to Railway
  if: success()
  run: railway up

Agent workflow

1. User: "deploy to railway"
2. Agent: Run railway-doctor check
3. If passes: railway up
4. If fails: railway-doctor fix, then re-check

Common Issues & Fixes

Issue 1: Import errors in Railway

Symptom: Works locally, fails in Railway with ModuleNotFoundError Cause: Import paths different in Railway vs local Check: railway-doctor validates critical imports Fix: Adjust sys.path or restructure imports

Issue 2: Lockfile out of sync

Symptom: Railway build fails with "dependency mismatch" Cause: pyproject.toml changed without poetry lock Check: railway-doctor validates lockfiles Fix: Auto-fixed with railway-doctor fix

Issue 3: Missing environment variables

Symptom: Railway 500 errors, missing DATABASE_URL etc. Cause: Env vars not set in Railway project Check: railway-doctor checks required vars (if Railway CLI installed) Fix: Manual setup via Railway dashboard or CLI

Issue 4: Railpack version breaking changes

Symptom: Build works locally, fails in Railway after Railpack update Cause: Railpack breaking change (e.g., 0.0.70 packageManager field) Prevention: Pin Railpack version in railway.toml

Monorepo Root Pattern (Python + llm-common)

Symptom: Works locally with ../packages/llm-common or a vendored copy, but Railway deploy fails with missing modules or broken imports.

Root Cause: Railway β€œisolated monorepo” deploys only the configured Root Directory (e.g., backend/). Anything outside that directory (../packages/llm-common) is invisible inside the container.

Best Practice Pattern:

  • Set Root Directory for Python services to backend/.
  • Use a standard dependency for shared libraries like llm-common, never a relative path:
    toml
    # backend/pyproject.toml
    [tool.poetry.dependencies]
    llm-common = { git = "https://github.com/stars-end/llm-common.git", tag = "v0.4.0", extras = ["pgvector"] }
    
  • Avoid path = "../llm-common" or packages/llm-common for runtime; those are fine for local dev only if the service is not deployed from that folder.
  • Start command should assume backend/ as CWD:
    bash
    poetry run uvicorn main:app --host 0.0.0.0 --port "$PORT"
    

Heuristic for Agents:

  • If a Railway deploy fails only in one repo (e.g., Affordabot) but works in another (Prime Radiant), first check:
    • Is the service using Root Directory = backend/?
    • Is llm-common (or any shared lib) installed as a normal dependency instead of via ../ paths?

Cross-Repo Deployment

This skill deploys to ~/.agent/skills/ and works across:

  • βœ… All repos (prime-radiant-ai, affordabot, any Railway project)
  • βœ… All AI agents (Claude Code, Codex CLI, Antigravity)
  • βœ… All VMs (shared via Universal Skills MCP)

Success Metrics

Baseline: 12 commits (17% of toil) wasted on Railway deployment failures Target: <2 commits per 60-commit cycle Impact: ~2-3 hours/month saved, fewer deployment iterations

Notes

Design Philosophy:

  • Fail fast locally (before pushing to Railway)
  • Validate critical imports (catches 80% of issues)
  • Clear guidance for non-auto-fixable issues
  • Agent-friendly (railway-doctor check β†’ fix β†’ deploy)

Why not full Railway simulator?

  • Over-engineering: Pre-flight + better logging gets 80% value
  • Complexity: Full simulator may still diverge from actual Railway
  • ROI: 2-3 days vs 1 day for similar impact

Complementary with:

  • Enhanced Railway logging (bd-vs87) - for debugging deployed errors
  • lockfile-doctor skill (bd-heb9) - for dependency management

Expand your agent's capabilities with these related and highly-rated skills.

stars-end/agent-skills

toolchain-health

Validate Python toolchain alignment between mise, Poetry, and pyproject. Use when changing Python versions, editing pyproject.toml, or seeing Poetry/mise version solver errors. Invokes /toolchain-health to check: - .mise.toml python tool version - pyproject.toml python constraint - Poetry env python interpreter Keywords: python version, mise, poetry, toolchain, env use, lock, install

0 0
Explore
stars-end/agent-skills

parallelize-cloud-work

Delegate independent work to Claude Code Web cloud sessions for parallel execution. Generates comprehensive session prompts with context exploration guidance, verifies Beads state, provides tracking commands. Use when user says "parallelize work to cloud", "start cloud sessions", or needs to execute multiple independent tasks simultaneously, or when user mentions cloud sessions, cloud prompts, delegate to cloud, Claude Code Web, generate session prompts, parallel execution, or asks "how do I use cloud sessions".

0 0
Explore
stars-end/agent-skills

docs-create

Create epic-specific documentation skill with external reference docs. MUST BE USED for caching external docs. Fetches URLs, caches full content, uses documentation-engineer to generate cohesive summaries, and creates auto-activating skill. Use when starting work on epic that requires external documentation context (API docs, tool guides, reference materials), or when user mentions "cache docs", "external docs", "API documentation", URLs for docs, documentation needs, reference materials, knowledge caching, or epic context documentation.

0 0
Explore
stars-end/agent-skills

git-safety-guard

Installs a Git safety guard hook for Claude Code to prevent destructive Git and filesystem commands. Blocks accidental data loss from commands like 'git checkout --', 'git reset --hard', 'git clean -f', 'git push --force', and 'rm -rf'. Use this skill to set up safety rails in a new or existing repository, or globally for the agent.

0 0
Explore
stars-end/agent-skills

beads-guard

Safe Beads workflow helper (warning-only). Use before bd sync/close/create to avoid JSONL conflicts. Ensures you are on a feature branch, up to date with origin/master, and stages Beads files cleanly with Feature-Key commits.

0 0
Explore
stars-end/agent-skills

vm-bootstrap

Linux VM bootstrap verification skill. MUST BE USED when setting up new VMs or verifying environment. Supports modes: check (warn-only), install (operator-confirmed), strict (CI-ready). Enforces Linux-only + mise as canonical; honors preference brew→npm (with apt fallback). Verifies required tools: mise, node, pnpm, python, poetry, gh, railway, bd, tmux, jq, rg. Handles optional tools as warnings: tailscale, playwright, docker, bv. Never prints/seeds secrets; never stores tokens in repo/YAML; Railway vars only for app runtime env. Safe on dirty repos (refuses and points to dirty-repo-bootstrap skill, or snapshots WIP branch). Keywords: vm, bootstrap, setup, mise, toolchain, linux, environment, provision, verify, new vm

0 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results