Hudu Company Page Returns 500 After Update Due to Failed Database Migration

After a Hudu platform update, company pages started returning 500 Internal Server Error. The root cause was a failed database migration that blocked all subsequent schema changes. Here is how we diagnosed and fixed it.

Published 2026-04-22 by TechNet New England

After updating Hudu, a company page started returning a 500 Internal Server Error. The browser console showed the failing request, but the real cause was buried in the application logs. This guide walks through the full diagnostic process and the fix. ## What You See in the Browser When you click on a company record in Hudu, the page fails to load. The browser console shows something like this: ``` GET https://docs.example.org/c/company-name-987c036a940b 500 (Internal Server Error) (anonymous) @ /app_assets/application-06eb8526.js:81 ``` You might also see a stack trace referencing Turbo or Hotwire JS functions like `issueRequest`, `visitStarted`, `proposeVisit`, and `followedLinkToLocation`. These are red herrings. The browser is just reporting that the server returned a 500. The problem is on the server side. ## Step 1: Check if It Is One Company or All Companies Before digging into logs, open a different company record. If other companies load fine, the issue might be bad data on that specific record. If all company pages fail, the problem is systemic, likely a schema or migration issue. In our case, all company pages were failing. ## Step 2: Check the Application Logs Since Hudu runs in Docker, you need to look at the container logs. First, find your service names: ```bash cd ~/hudu2 sudo docker compose ps sudo docker compose config --services ``` Typical Hudu services are `app`, `worker`, `db`, `redis`, and possibly `letsencrypt` for the reverse proxy. There is no `nginx` service in a standard Hudu Docker setup. Follow the logs: ```bash cd ~/hudu2 sudo docker compose logs -f app worker ``` Then reload the broken company page in your browser. Watch for error lines. In our case, the logs showed: ``` PG::UndefinedColumn: ERROR: column "position" does not exist ActionView::Template::Error Completed 500 Internal Server Error ``` This tells us the Hudu application code expects a database column called `position` that does not exist. The database schema is out of sync with the application code. ## Step 3: Check Migration Status The schema mismatch means database migrations did not complete during the update. Check their status: ```bash cd ~/hudu2 sudo docker compose exec app bundle exec rails db:migrate:status ``` Look for any migration with a `down` status. Those are migrations that have not been applied yet. ## Step 4: Run Migrations Try running the pending migrations: ```bash cd ~/hudu2 sudo docker compose exec app bundle exec rails db:migrate ``` In our case, this failed immediately: ``` Migrating to FixPhotosMissingCompanyId (20250807230436) Validation failed: Company cannot be set directly. Change the photoable to update the company. ``` The migration stopped at `FixPhotosMissingCompanyId`. Because it failed, every migration after it never ran. That is why the `position` column was missing: the migration that adds it comes later in the sequence. ## Root Cause The failing migration file (`20250807230436_fix_photos_missing_company_id.rb`) contains this code: ```ruby affected_photos.find_each(batch_size: 100) do |photo| photo.update!(company_id: photo.photoable_id) end ``` The `update!` method runs Active Record model validations. In the newer version of Hudu, the Photo model has a validation that rejects direct assignment of `company_id`. The migration was written for an older version of the model. When it runs against the newer model code, the validation fires and the migration aborts. This is a classic Rails problem: migrations should not rely on model validations because those validations change between versions. ## The Fix ### Back Up the Database First Always back up before modifying migrations: ```bash cd ~/hudu2 sudo docker compose exec -T db pg_dump -U postgres hudu_production > /tmp/hudu-pre-fix-$(date +%F-%H%M).sql ``` ### Review the Migration File Confirm the problem line: ```bash cd ~/hudu2 sudo docker compose exec app sed -n '1,220p' /var/www/hudu2/db/migrate/20250807230436_fix_photos_missing_company_id.rb ``` Look for the line with `photo.update!`. ### Patch the Migration The fix is to replace `update!` with `update_columns`. The `update_columns` method writes directly to the database without running model validations or callbacks. Open a shell inside the app container: ```bash cd ~/hudu2 sudo docker compose exec app sh ``` Apply the patch: ```bash sed -i 's/photo.update!(company_id: photo.photoable_id)/photo.update_columns(company_id: photo.photoable_id)/' /var/www/hudu2/db/migrate/20250807230436_fix_photos_missing_company_id.rb ``` Verify the change: ```bash grep -n "update" /var/www/hudu2/db/migrate/20250807230436_fix_photos_missing_company_id.rb ``` You should see `update_columns` instead of `update!`. Exit the container: ```bash exit ``` ### Run Migrations Again ```bash cd ~/hudu2 sudo docker compose exec app bundle exec rails db:migrate ``` This time the `FixPhotosMissingCompanyId` migration should complete, and all subsequent migrations (including the one that adds the `position` column) will run. ### Restart Hudu ```bash cd ~/hudu2 sudo docker compose restart app worker ``` ### Test Reload the company page that was returning the 500 error. It should load normally. ## Verification Checklist After the fix, run through these checks: 1. Open the previously failing company page. Confirm it loads. 2. Check logs for any remaining errors: ```bash cd ~/hudu2 sudo docker compose logs -f app worker ``` 3. Verify all migrations are applied: ```bash cd ~/hudu2 sudo docker compose exec app bundle exec rails db:migrate:status ``` All migrations should show `up` status. 4. Spot check other sections of the company record: Overview, Assets, Passwords, Websites, Networks, KB, Activity. Make sure nothing else is broken. ## Important Notes - This issue was **not caused by the reverse proxy** (SWAG, Nginx Proxy Manager, or whatever you use in front of Hudu). - This issue was **not caused by the browser**. The JavaScript errors in the console are symptoms, not the cause. - The Hudu update pulled newer application code, but database migrations did not complete successfully. The application code expected schema changes that never happened. - The fix was to address the stuck migration first, which unblocked all remaining migrations. ## Why This Happens Rails migrations run in sequence. If migration #5 out of 20 fails, migrations #6 through #20 never execute. The application code, however, already expects all 20 migrations to have run. This creates a mismatch between what the code expects and what the database actually has. The `update!` vs `update_columns` distinction is a common gotcha in Rails. Migrations should generally avoid triggering model validations because the validation rules may have changed between versions. A migration written for v2.34 might fail when running against v2.35 model code because new validations were added. ## Quick Reference If you hit a 500 after a Hudu update, always check migration status first: ```bash cd ~/hudu2 sudo docker compose exec app bundle exec rails db:migrate:status ``` If you see any migration with `down` status, that is your starting point. Fix the blocked migration and the rest will follow. --- *Running into issues with Hudu, IT documentation platforms, or Docker-based applications? [Contact TechNet New England](/contact) for expert support.*