Introduction

Tilt's live update feature is not updating running containers when files change. Code changes are not reflected in the running application.

Symptoms

```bash $ tilt up

# File changes detected but not applied: [demo] Build Failed: failed to sync files ```

Sync error:

bash
Error: no sync or run_in_container specified for live_update

Container error:

bash
Error: container not found: app

Permission error:

bash
Error: permission denied: /app/src

Common Causes

  1. 1.Live_update not configured - Missing live_update section in Tiltfile
  2. 2.Sync paths wrong - Source paths don't match container paths
  3. 3.Container name wrong - fall_back_on or container specified incorrectly
  4. 4.Dockerfile incompatible - Dockerfile doesn't support file updates
  5. 5.Permission issues - Container user can't write to synced directories
  6. 6.Process not reloading - Application needs restart after file changes

Step-by-Step Fix

  1. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 6.Verify the fix

Step 1: Check Tiltfile Configuration

```python # View Tiltfile: cat Tiltfile

# Check live_update configuration: cat Tiltfile | grep -A10 "live_update"

# Basic live_update syntax: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), run('cd /app && npm install', trigger='./package.json'), ] )

# Check if docker_build has live_update: docker_build( 'my-image', '.', # Missing live_update = full rebuild only )

# Add live_update: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), ] )

# Validate Tiltfile: tilt ci

# Check Tiltfile syntax: tilt dump > tilt-config.json cat tilt-config.json | jq '.' ```

Step 2: Verify Sync Paths

```python # Check sync paths: # Format: sync('local_path:container_path')

# Verify local path exists: ls ./src

# Check container path in Dockerfile: cat Dockerfile | grep WORKDIR cat Dockerfile | grep COPY

# Common sync configurations: # For Node.js: sync('./src:/app/src')

# For Python: sync('./app:/app/app')

# For Go: sync('./cmd:/app/cmd') sync('./pkg:/app/pkg')

# Multiple syncs: live_update=[ sync('./src:/app/src'), sync('./public:/app/public'), ]

# Check sync in Tilt UI: # Open Tilt UI -> Click resource -> View "Build History" # Look for "Live Update" in build log

# Test sync manually: docker exec -it <container> ls /app/src ```

Step 3: Add run Commands

```python # Add run_in_container for updates: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), run('pip install -r requirements.txt', trigger='./requirements.txt'), ] )

# Run on container: # run() - runs in container after sync # run_local() - runs on host machine

# Restart application: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), run('pkill -f "python" || true'), # Kill process run('python /app/main.py &'), # Restart ] )

# Use trigger for selective updates: live_update=[ sync('./src:/app/src'), run('npm install', trigger='./package.json'), # Only on package.json change run('npm run build', trigger='./src/**/*.ts'), # Only on TS file changes ]

# Fall back on full rebuild: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), ], match_in_env_vars=True, # Check env vars for image name ) ```

Step 4: Fix Container Permissions

```bash # Check container user: docker exec -it <container> whoami

# Check file permissions in container: docker exec -it <container> ls -la /app

# If permission denied, fix in Dockerfile: # Option 1: Run as root USER root

# Option 2: Fix directory permissions RUN chown -R app:app /app

# Option 3: Use chmod RUN chmod -R 755 /app

# Check if container has write access: docker exec -it <container> touch /app/src/test.txt

# Fix with run command: live_update=[ sync('./src:/app/src'), run('chown -R app:app /app/src || true'), ]

# Check container user in Dockerfile: cat Dockerfile | grep USER ```

Step 5: Configure Fallback Strategy

```python # Set fallback_on for rebuild triggers: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), ], fallback_on=[ './requirements.txt', # Full rebuild on requirements change './Dockerfile', # Full rebuild on Dockerfile change ] )

# Only build on changes: docker_build( 'my-image', '.', only=['./src', './package.json'], # Only watch these paths live_update=[ sync('./src:/app/src'), ] )

# Ignore files: docker_build( 'my-image', '.', ignore=['./node_modules', './.git'], live_update=[ sync('./src:/app/src'), ] )

# Set container target for live_update: docker_build( 'my-image', '.', live_update=[ sync('./src:/app/src'), ], target='development', # Build this Dockerfile stage ) ```

Step 6: Use k8s_yaml and k8s_resource

```python # Check resource configuration: cat Tiltfile | grep -A5 "k8s_resource"

# Associate image with resource: docker_build('my-image', '.', live_update=[sync('./src:/app/src')])

k8s_yaml('kubernetes.yaml')

k8s_resource( 'my-app', port_forwards=8080, extra_pod_selectors=[{'app': 'my-app'}] )

# Set resource name: k8s_resource( 'my-app', new_name='demo', # Rename in Tilt UI port_forwards=8080, )

# Multiple resources: k8s_resource('app1', port_forwards=8080) k8s_resource('app2', port_forwards=8081)

# Check resource pod: tilt get pods

# View resource status: tilt get resources ```

Step 7: Debug Live Update

```bash # Enable verbose logging: tilt up --verbose

# Check Tilt logs: tilt logs

# View Tilt UI: # Open http://localhost:10350

# Check file watcher: # In Tiltfile, add: watch_file('./config.yaml')

# Trigger manual rebuild: tilt trigger <resource-name>

# View build history: # In Tilt UI -> Resource -> Build History

# Check for file sync errors: tilt logs | grep -i "sync|update|error"

# Test container update manually: docker cp ./src/file.py <container>:/app/src/file.py docker exec <container> cat /app/src/file.py ```

Step 8: Fix Process Reload

```python # Applications may need restart after file sync:

# Python with gunicorn: live_update=[ sync('./src:/app/src'), run('kill -HUP 1'), # Signal gunicorn to reload ]

# Node.js with nodemon: # Use nodemon in Dockerfile: CMD ["nodemon", "index.js"] # Files sync, nodemon auto-reloads

# Go with CompileDaemon: # In Dockerfile: CMD ["CompileDaemon", "-build=go build -o app .", "-command=./app"] # Or use air for hot reload: CMD ["air"]

# Java with Spring Boot DevTools: # Add dependency and: live_update=[ sync('./src:/app/src'), run('./mvnw compile'), ]

# Generic restart: live_update=[ sync('./src:/app/src'), run('pkill -f "main.py" || true'), run('python /app/main.py &'), ] ```

Step 9: Check Dockerfile Compatibility

```dockerfile # Check Dockerfile for live_update compatibility:

# Bad: Entrypoint blocks sync ENTRYPOINT ["./start.sh"]

# Good: CMD can be overridden CMD ["python", "main.py"]

# Bad: Single layer COPY . /app RUN pip install -r requirements.txt && pip cache purge

# Good: Separate layers COPY requirements.txt /app/ RUN pip install -r requirements.txt COPY . /app

# Use multi-stage for smaller updates: FROM node:18 AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build

FROM node:18 AS runtime WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules CMD ["node", "dist/main.js"]

# Target development stage: docker_build( 'my-image', '.', target='development', # Use development stage live_update=[ sync('./src:/app/src'), ] ) ```

Step 10: Tilt Verification Script

```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-tilt-live-update.sh #!/bin/bash

echo "=== Tiltfile Content ===" cat Tiltfile

echo "" echo "=== Docker Build Config ===" grep -A20 "docker_build" Tiltfile

echo "" echo "=== Live Update Config ===" grep -A10 "live_update" Tiltfile

echo "" echo "=== Dockerfile WORKDIR ===" grep -i "WORKDIR|COPY|CMD" Dockerfile

echo "" echo "=== Current Directory ===" ls -la

echo "" echo "=== Source Files ===" ls -la ./src 2>/dev/null || ls -la ./app 2>/dev/null || echo "No src or app directory"

echo "" echo "=== Tilt Status ===" tilt get resources 2>/dev/null || echo "Tilt not running"

echo "" echo "=== Docker Containers ===" docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

echo "" echo "=== Test File Sync ===" touch ./src/.tilt-test-$(date +%s) echo "Created test file, check Tilt UI for sync"

echo "" echo "=== Recommendations ===" echo "1. Add live_update to docker_build in Tiltfile" echo "2. Verify sync paths match container paths" echo "3. Check container has write permissions" echo "4. Add run commands to restart application" echo "5. Use fallback_on for dependency changes" echo "6. Ensure Dockerfile supports file updates" echo "7. Check application reload mechanism" EOF

chmod +x /usr/local/bin/check-tilt-live-update.sh

# Usage: /usr/local/bin/check-tilt-live-update.sh ```

Tilt Live Update Checklist

CheckExpected
live_update definedIn docker_build
Sync paths correctLocal:Container match
Container permissionsWrite access to sync dir
Process reloadApp restarts on change
Fallback configuredFull rebuild on key changes
Dockerfile compatibleCMD not blocking
Files monitoredTilt sees file changes

Verification

```bash # After fixing Tilt live update

# 1. Start Tilt tilt up // Tilt UI opens

# 2. Make file change echo "// test" >> src/main.py // Tilt shows live update

# 3. Check container docker exec -it <container> cat /app/src/main.py // Change reflected

# 4. View build history # In Tilt UI -> Resource -> Build History // Live Update appears

# 5. Test multiple changes # Make several file changes // Updates applied incrementally

# 6. Check application curl http://localhost:8080 // Response reflects changes ```

  • [Fix Docker Compose Up Failed](/articles/fix-docker-compose-up-failed)
  • [Fix Skaffold Build Failed](/articles/fix-skaffold-build-failed)
  • [Fix Kubernetes Deployment Not Working](/articles/fix-kubernetes-deployment-not-working)
  • [Technical troubleshooting: Fix Cicd Artifact Upload Failed Storage Issue in C](cicd-artifact-upload-failed-storage)
  • [Technical troubleshooting: Fix Cicd Code Quality Gate Failed Sonarqube Issue ](cicd-code-quality-gate-failed-sonarqube)
  • [Technical troubleshooting: Fix Cicd Deployment Failed Health Check Issue in C](cicd-deployment-failed-health-check)
  • [Technical troubleshooting: Fix Cicd Github Actions Workflow Queue Timeout in ](cicd-github-actions-workflow-queue-timeout)
  • [Technical troubleshooting: Fix Cicd Gitlab Runner Stuck Pending Issue in CI/C](cicd-gitlab-runner-stuck-pending)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Tilt Live Update Not Working", "description": "Troubleshoot Tilt live update not working. Check sync, container, dependencies.", "url": "https://www.fixwikihub.com/fix-tilt-live-update-not-working", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-08T21:29:38.998Z", "dateModified": "2026-04-08T21:29:38.998Z" } </script>