Troubleshooting
Troubleshooting
Section titled “Troubleshooting”This guide covers common issues you might encounter when working with YAPL and how to resolve them.
Installation Issues
Section titled “Installation Issues”Package Not Found
Section titled “Package Not Found”Error:
npm ERR! 404 Not Found - GET https://registry.npmjs.org/yapl
Solution: Use the correct package name:
npm install @yapl-language/yapl.ts
Import Errors
Section titled “Import Errors”Error:
Cannot find module 'yapl' or its corresponding type declarations
Solution: Use the correct import:
import { NodeYAPL } from "@yapl-language/yapl.ts";
Template Syntax Errors
Section titled “Template Syntax Errors”Missing File Extensions
Section titled “Missing File Extensions”Error:
ENOENT: no such file or directory, open '/path/to/base/system'
Problem:
{% extends "base/system" %}
Solution: Always include file extensions:
{% extends "base/system.md.yapl" %}
Mismatched Block Tags
Section titled “Mismatched Block Tags”Error:
Template parsing error: Missing {% endif %}
Problem:
{% if condition %} Content here{# Missing {% endif %} #}
Solution: Ensure all control structures are properly closed:
{% if condition %} Content here{% endif %}
Invalid Block Names
Section titled “Invalid Block Names”Error:
Template parsing error: Invalid block name
Problem:
{% block 123invalid %}Content{% endblock %}
Solution: Use valid block names (letters, numbers, underscores, hyphens, colons):
{% block valid_block_name %}Content{% endblock %}
Runtime Errors
Section titled “Runtime Errors”Path Traversal Blocked
Section titled “Path Traversal Blocked”Error:
Error: Path escapes baseDir: ../../../etc/passwd
Cause:
Attempting to access files outside the configured baseDir
with strictPaths: true
.
Solutions:
- Use relative paths within baseDir:
{% extends "../base/system.md.yapl" %} {# OK if within baseDir #}
- Disable strict paths (not recommended for production):
const yapl = new NodeYAPL({ baseDir: "./prompts", strictPaths: false,});
- Adjust your baseDir:
const yapl = new NodeYAPL({ baseDir: "./parent-directory", // Set higher in directory tree strictPaths: true,});
Maximum Depth Exceeded
Section titled “Maximum Depth Exceeded”Error:
Error: Max template depth exceeded (possible recursion).
Cause: Circular dependencies or deeply nested templates.
Common Causes:
- Circular includes:
{# template1.yapl #}{% include "template2.yapl" %}
{# template2.yapl #}{% include "template1.yapl" %} {# Circular! #}
- Self-referencing templates:
{# template.yapl #}{% include "template.yapl" %} {# Self-reference! #}
Solutions:
- Check for circular dependencies
- Increase maxDepth if legitimately needed:
const yapl = new NodeYAPL({ baseDir: "./prompts", maxDepth: 50, // Default is 20});
For Loop Type Errors
Section titled “For Loop Type Errors”Error:
Error: For loop iterable must be an array, got: string
Problem:
{% for char in "hello" %} {# String, not array #} {{ char }}{% endfor %}
Solution: Ensure you’re iterating over arrays:
{% for item in items %} {# items must be an array #} {{ item }}{% endfor %}
Or convert strings to arrays in your data:
const data = { characters: "hello".split(""), // ["h", "e", "l", "l", "o"]};
File System Issues
Section titled “File System Issues”File Not Found
Section titled “File Not Found”Error:
ENOENT: no such file or directory, open '/path/to/template.yapl'
Debugging Steps:
- Check file exists:
ls -la /path/to/template.yapl
- Verify baseDir configuration:
console.log("Base directory:", yapl.baseDir);
- Check file permissions:
ls -la /path/to/
- Use absolute paths for debugging:
const yapl = new NodeYAPL({ baseDir: path.resolve("./prompts"), // Absolute path});
Permission Denied
Section titled “Permission Denied”Error:
EACCES: permission denied, open '/path/to/template.yapl'
Solutions:
- Check file permissions:
chmod 644 /path/to/template.yapl
- Check directory permissions:
chmod 755 /path/to/directory
- Run with appropriate user permissions
Variable Issues
Section titled “Variable Issues”Undefined Variables
Section titled “Undefined Variables”Problem: Variables showing as empty in output.
Debugging:
const result = await yapl.renderString("{{ missing_var }}", {});console.log(result.content); // Empty string
Solutions:
- Use default values:
{{ missing_var | default("fallback value") }}
- Check variable names:
const data = { userName: "Alice", // camelCase};
// This won't work:// {{ user_name }}
// This will work:// {{ userName }}
- Debug variable access:
{# Debug output #}Available variables: {{ . }}User name: {{ user.name }}
Nested Property Access
Section titled “Nested Property Access”Problem:
{{ user.profile.email }} {# Returns empty #}
Debugging:
const data = { user: { profile: { email: "alice@example.com", }, },};
// Check data structureconsole.log(JSON.stringify(data, null, 2));
Common Issues:
- Null/undefined in chain:
const data = { user: null, // This breaks user.profile.email};
- Typos in property names:
const data = { user: { profil: { // Typo: should be "profile" email: "alice@example.com", }, },};
Browser-Specific Issues
Section titled “Browser-Specific Issues”File Loading Not Available
Section titled “File Loading Not Available”Error:
Error: File loading is not available. Provide a loadFile function in YAPLOptions or use renderString for browser usage.
Problem:
import { YAPL } from "@yapl-language/yapl.ts";
const yapl = new YAPL({ baseDir: "/templates" });await yapl.render("template.yapl"); // Error!
Solution:
Use renderString
in browsers:
import { YAPL } from "@yapl-language/yapl.ts";
const yapl = new YAPL({ baseDir: "/templates" });const templateContent = await fetch("/templates/template.yapl").then((r) => r.text());const result = await yapl.renderString(templateContent, variables);
Or provide custom file loading:
const yapl = new YAPL({ baseDir: "/templates", loadFile: async (path) => { const response = await fetch(path); return response.text(); }, resolvePath: (templateRef, fromDir, ensureExt) => { return new URL(ensureExt(templateRef), fromDir).href; },});
Performance Issues
Section titled “Performance Issues”Slow Template Rendering
Section titled “Slow Template Rendering”Symptoms:
- Long render times
- High memory usage
- Timeouts
Debugging:
- Enable caching:
const yapl = new NodeYAPL({ baseDir: "./prompts", cache: true, // Enable file caching});
- Profile template complexity:
console.time("render");const result = await yapl.render("complex-template.yapl", data);console.timeEnd("render");
- Check template depth:
console.log("Used files:", result.usedFiles.length);
Solutions:
- Reduce template nesting
- Simplify complex conditionals
- Break large templates into smaller pieces
- Pre-process complex data structures
Memory Leaks
Section titled “Memory Leaks”Symptoms:
- Increasing memory usage over time
- Out of memory errors
Solutions:
- Disable caching for development:
const yapl = new NodeYAPL({ baseDir: "./prompts", cache: false, // Disable for development});
- Create new instances periodically:
// For long-running processeslet yapl = new NodeYAPL(options);
setInterval(() => { yapl = new NodeYAPL(options); // Fresh instance}, 1000 * 60 * 60); // Every hour
Debugging Techniques
Section titled “Debugging Techniques”Enable Verbose Logging
Section titled “Enable Verbose Logging”// Add debug output to templatesconst debugTemplate = `{# Debug info #}Variables: {{ . }}User: {{ user }}Config: {{ config }}
{# Original template #}${originalTemplate}`;
Inspect Rendered Output
Section titled “Inspect Rendered Output”const result = await yapl.renderString(template, variables);
// Show exact output with whitespaceconsole.log("Content:", JSON.stringify(result.content));
// Show used filesconsole.log("Used files:", result.usedFiles);
Test Templates in Isolation
Section titled “Test Templates in Isolation”// Test individual componentsconst componentResult = await yapl.renderString( '{% include "components/header.yapl" %}', testData);
Validate Data Structures
Section titled “Validate Data Structures”// Check data before renderingfunction validateData(data) { console.log("Data structure:"); console.log(JSON.stringify(data, null, 2));
// Check for common issues if (data.user && !data.user.name) { console.warn("Warning: user.name is missing"); }}
validateData(templateData);const result = await yapl.render("template.yapl", templateData);
Getting Help
Section titled “Getting Help”Check the Documentation
Section titled “Check the Documentation”- Syntax Reference - Complete syntax guide
- API Reference - Full API
Common Resources
Section titled “Common Resources”- GitHub Issues: Report bugs and request features
- Discord Community: Get help from other users
- Stack Overflow: Search for
yapl
tag
Providing Bug Reports
Section titled “Providing Bug Reports”When reporting issues, include:
- YAPL version:
npm list @yapl-language/yapl.ts
- Minimal reproduction case:
import { NodeYAPL } from "@yapl-language/yapl.ts";
const yapl = new NodeYAPL({ baseDir: "./test" });const result = await yapl.renderString("{{ test }}", { test: "value" });console.log(result.content);
- Error messages and stack traces
- Expected vs actual behavior
- Environment details (Node.js version, OS, etc.)
This troubleshooting guide should help you resolve most common issues with YAPL. If you encounter problems not covered here, please check the documentation or reach out to the community for help.