Skip to main content

Troubleshooting Common Issues

This guide helps you diagnose and fix common issues when deploying and running applications on the Strongly platform.

Build Failures

Build Timeout (20 minutes)

Problem: Build exceeds 20-minute timeout limit

Symptoms:

  • Build status changes to timeout
  • Build logs show timeout error
  • Large dependencies downloading
  • Complex build steps

Solutions:

  1. Optimize Docker build:
# Use .dockerignore to exclude unnecessary files
node_modules
.git
*.log

# Use multi-stage builds
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:18-alpine
COPY --from=builder /app/dist ./dist
  1. Leverage layer caching:
# Copy package files first (changes less often)
COPY package*.json ./
RUN npm ci

# Copy code last (changes more often)
COPY . .
  1. Reduce dependencies:
// Remove unnecessary devDependencies
{
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {}
}

Build Status Flow

Builds progress through these statuses:

pending -> building -> completed (success)
-> failed (build error)
-> cancelled (user cancelled)
-> timeout (exceeded 20 minutes)

App Builder Unreachable

Problem: Cannot connect to the app builder service

Symptoms:

  • Error: app-builder-unreachable
  • Error: Cannot connect to app builder service
  • Deployment fails before build starts

Solutions:

  1. Check service status: The app-builder backend may be down or restarting
  2. Retry deployment: Wait a moment and try again
  3. Check network: Ensure the frontend can reach the backend URL configured in settings
  4. Check logs: Look at the server logs for connection errors

Dockerfile Syntax Errors

Problem: Invalid Dockerfile syntax

Symptoms:

  • Build fails immediately
  • Error: "Dockerfile parse error"

Common Issues:

# Bad: Missing WORKDIR
COPY . .

# Good: Set WORKDIR first
WORKDIR /app
COPY . .

# Bad: Wrong order (FROM must be first)
RUN apt-get update
FROM node:18

# Good: FROM first
FROM node:18
RUN apt-get update

# Bad: Missing quotes for paths with spaces
COPY my folder /app

# Good: Quote paths
COPY "my folder" /app

Solution: Validate Dockerfile locally before deploying:

docker build -t test .

Missing Files in Build Context

Problem: Files not found during build

Symptoms:

  • COPY command fails
  • Module not found errors

Solutions:

  1. Check archive structure:
# Dockerfile and manifest must be in root
app.tar.gz
├── Dockerfile
├── strongly.manifest.yaml
├── package.json
└── src/
  1. Verify .dockerignore isn't excluding needed files:
# Don't ignore required files
!package.json
!src/
  1. Use correct COPY paths:
# Relative to build context root
COPY package.json ./
COPY src/ ./src/

Stale Builds

Problem: Old builds lingering in pending or building state

Solutions:

  1. Check if the build is still actively running
  2. If stuck, the platform has a stale build cleanup endpoint that can be triggered by administrators
  3. Create a new deployment which will start a fresh build

Application Startup Issues

Health Check Failures

Problem: App deployed but health checks fail

Symptoms:

  • Status shows "Unhealthy"
  • Pods continuously restart
  • "CrashLoopBackOff" status

Solutions:

  1. Implement health check endpoint:
// Express.js
app.get('/health', (req, res) => {
res.status(200).json({ status: 'ok' });
});
  1. Verify health check path in manifest:
health_check:
path: /health # Must match your endpoint
port: 3000
initial_delay: 15 # Give app time to start
  1. Increase startup timeout (in manifest runtime section):
runtime:
startup_timeout: 120 # Give more time for slow-starting apps
  1. Check application logs:
Navigate to app details -> Logs tab
Look for startup errors
  1. Test locally:
docker run -p 3000:3000 my-app
curl http://localhost:3000/health

Port Binding Errors

Problem: Application fails to start due to port conflicts

Symptoms:

  • "Port already in use"
  • "EADDRINUSE" error
  • App crashes on startup

Solutions:

  1. Match port in code and manifest:
// server.js
const PORT = process.env.PORT || 3000;
app.listen(PORT);
# manifest
ports:
- port: 3000
expose: true
  1. Use PORT environment variable:
// Always use environment variable
const PORT = process.env.PORT;
if (!PORT) {
throw new Error('PORT environment variable not set');
}

Missing Environment Variables

Problem: App crashes due to missing configuration

Symptoms:

  • "Environment variable not defined"
  • "Cannot read property of undefined"
  • Database connection errors

Solutions:

  1. Check STRONGLY_SERVICES is parsed correctly:
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const services = data.services || {};

// Check addons
const mongoAddons = services.addons?.mongodb || [];
if (mongoAddons.length === 0) {
throw new Error('No MongoDB addon configured');
}
  1. Provide default values:
const LOG_LEVEL = process.env.LOG_LEVEL || 'info';
const TIMEOUT = parseInt(process.env.TIMEOUT || '30000');
  1. Validate required variables on startup:
const required = ['DATABASE_URL', 'JWT_SECRET'];
const missing = required.filter(v => !process.env[v]);

if (missing.length > 0) {
throw new Error(`Missing required env vars: ${missing.join(', ')}`);
}
  1. Check manifest configuration:
env:
- name: DATABASE_URL
value: ""
required: true # Platform will enforce this
secret: true

Out of Memory (OOM) Errors

Problem: Application killed due to memory limit

Symptoms:

  • Status: "OOMKilled"
  • Pods restart frequently
  • "JavaScript heap out of memory"

Solutions:

  1. Increase memory limit:
# manifest
resources:
memory_request: "1Gi"
memory_limit: "2Gi" # Increase from 512Mi
  1. Optimize application code:
// Bad: Loading entire dataset
const data = await db.collection.find().toArray();

// Good: Use streaming or pagination
const cursor = db.collection.find();
for await (const doc of cursor) {
process(doc);
}
  1. Increase Node.js heap size:
CMD ["node", "--max-old-space-size=1536", "server.js"]
  1. Enable autoscaling with memory threshold:
# Autoscaling config
memory_threshold: 70% # Scale before hitting limit

Service Connection Issues

Database Connection Failures

Problem: Cannot connect to database

Symptoms:

  • "ECONNREFUSED"
  • "Connection timeout"
  • "Authentication failed"

Solutions:

  1. Verify service is connected (using correct STRONGLY_SERVICES structure):
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const services = data.services || {};

// List all addon types
console.log('Addon types:', Object.keys(services.addons || {}));

// List all datasource types
console.log('Datasource types:', Object.keys(services.datasources || {}));
  1. Use correct access pattern:
// MongoDB addon
const mongoAddons = services.addons?.mongodb || [];
if (mongoAddons.length > 0) {
const mongo = mongoAddons[0];
const connectionString = mongo.connection?.connection_string;
console.log('MongoDB host:', mongo.connection?.host);
}

// PostgreSQL datasource
const pgSources = services.datasources?.postgres || [];
if (pgSources.length > 0) {
const pg = pgSources[0];
console.log('PG host:', pg.connection?.host);
console.log('PG auth:', pg.auth?.method);
}
  1. Test connection separately:
const { MongoClient } = require('mongodb');

async function testConnection() {
try {
const client = await MongoClient.connect(connectionString);
console.log('Connected to database');
await client.close();
} catch (err) {
console.error('Connection failed:', err.message);
}
}
  1. Check service health:
Navigate to Add-ons -> Click addon name -> Check status
Ensure addon is "Running"

AI Model API Errors

Problem: Cannot call AI model

Symptoms:

  • "Unauthorized"
  • "Model not found"
  • Connection timeout

Solutions:

  1. Verify AI Gateway configuration:
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const aiGateway = data.services?.aigateway;

console.log('AI Gateway base URL:', aiGateway?.base_url);
console.log('Available models:', aiGateway?.available_models?.length);

// List models
for (const model of aiGateway?.available_models || []) {
console.log(` - ${model.display_name} (${model.vendor_model_id})`);
console.log(` Type: ${model.type}, Model Type: ${model.model_type}`);
}
  1. Check API request format:
const model = aiGateway.available_models[0];

const response = await fetch(`${aiGateway.base_url}/v1/chat/completions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Model-Id': model._id // Use the Strongly model ID
},
body: JSON.stringify({
model: model.vendor_model_id, // Use vendor model ID
messages: [{ role: 'user', content: 'Hello' }]
})
});

if (!response.ok) {
const error = await response.text();
console.error('API error:', error);
}
  1. Verify model is available (for self-hosted models):
Navigate to AI Gateway -> Models -> Check status
Ensure model is "Active"

Workflow Trigger Failures

Problem: Cannot invoke workflow

Symptoms:

  • "Workflow not found"
  • "Workflow execution failed"
  • No response from workflow

Solutions:

  1. Verify workflow configuration:
const data = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const workflows = data.services?.workflows?.available_workflows || [];

for (const wf of workflows) {
console.log(`Workflow: ${wf.name} (${wf.id})`);
console.log(` Trigger: ${wf.trigger_type}`);
console.log(` URL: ${wf.endpoints?.proxy_url}`);
console.log(` Method: ${wf.endpoints?.method}`);
}
  1. Check request format:
const workflow = workflows[0];

const response = await fetch(workflow.endpoints.proxy_url, {
method: workflow.endpoints.method || 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
// Match the workflow's input_schema
input: 'data'
})
});

const result = await response.json();
console.log('Workflow result:', result);
  1. Verify workflow is active:
Navigate to Workflows -> Check workflow status
Ensure workflow is "Active" and deployed

Performance Issues

High CPU Usage

Problem: CPU usage consistently high

Solutions:

  1. Profile your application:
// Node.js CPU profiling
node --prof server.js
node --prof-process isolate-*.log > profile.txt
  1. Optimize hot code paths:
// Bad: Synchronous operation in request handler
app.get('/users', (req, res) => {
const data = fs.readFileSync('users.json'); // Blocks event loop
res.json(JSON.parse(data));
});

// Good: Asynchronous operation
app.get('/users', async (req, res) => {
const data = await fs.promises.readFile('users.json');
res.json(JSON.parse(data));
});
  1. Add caching:
const cache = new Map();

app.get('/users', async (req, res) => {
if (cache.has('users')) {
return res.json(cache.get('users'));
}

const users = await db.users.find().toArray();
cache.set('users', users);
setTimeout(() => cache.delete('users'), 60000); // 1 min TTL

res.json(users);
});
  1. Scale horizontally:
# Enable autoscaling
cpu_threshold: 60% # Lower threshold
max_replicas: 10

Slow Response Times

Problem: API responses are slow

Solutions:

  1. Add database indexes:
-- Check slow queries
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

-- Add index
CREATE INDEX idx_users_email ON users(email);
  1. Implement connection pooling:
// Bad: New connection per request
app.get('/users', async (req, res) => {
const client = new MongoClient(url);
await client.connect();
const users = await client.db().collection('users').find().toArray();
await client.close();
res.json(users);
});

// Good: Connection pool
const pool = new MongoClient(url, { maxPoolSize: 10 });
await pool.connect();

app.get('/users', async (req, res) => {
const users = await pool.db().collection('users').find().toArray();
res.json(users);
});
  1. Add pagination:
app.get('/users', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = 20;
const skip = (page - 1) * limit;

const users = await db.users
.find()
.skip(skip)
.limit(limit)
.toArray();

res.json({ users, page, hasMore: users.length === limit });
});

Deployment Issues

Cannot Redeploy

Problem: Redeploy doesn't work

Solutions:

  1. Check app status is not "Deploying"
  2. Wait for current operation to complete
  3. Try stopping and starting app first
  4. Contact support if stuck

Getting Help

Diagnostic Information

When contacting support, provide:

  1. App ID and Name
  2. Error logs from app details page
  3. Build logs if build failed
  4. Build status (pending, building, completed, failed, cancelled, timeout)
  5. Steps to reproduce the issue
  6. Screenshots of errors
  7. Manifest file content

Enable Debug Logging

# manifest
env:
- name: LOG_LEVEL
value: "debug" # Or "DEBUG" for Python
// Node.js
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info'
});

Common Log Patterns

Connection Refused:

Error: connect ECONNREFUSED 10.0.2.15:5432
-> Database not running or wrong host/port

Out of Memory:

<--- Last few GCs --->
FATAL ERROR: Reached heap limit
-> Increase memory limit or optimize code

Module Not Found:

Error: Cannot find module 'express'
-> Dependency not installed, check package.json

Port in Use:

Error: listen EADDRINUSE: address already in use :::3000
-> Port conflict, check manifest configuration

App Builder Unreachable:

Error: app-builder-unreachable - Cannot connect to app builder service
-> App builder backend is down or network issue

Next Steps