This guide helps you diagnose and resolve common issues when working with putior. Each section covers a specific category of problems with practical solutions.
These are the top 5 issues users encounter. Check these first!
Frequency: đź”´ Very Common
Problem: put() returns an empty data
frame even though you have annotations in your files.
Cause: Wrong comment prefix for your file type.
Solution: Use the correct comment prefix for your language:
| Language | Correct Prefix | Example |
|---|---|---|
| R, Python | # put |
# put label:"Step 1" |
| SQL, Lua | -- put |
-- put label:"Step 1" |
| JavaScript, Go, C | // put |
// put label:"Step 1" |
| MATLAB | % put |
% put label:"Step 1" |
# Check what prefix your file type needs
get_comment_prefix("sql") # Returns "--"
get_comment_prefix("js") # Returns "//"Frequency: đź”´ Very Common
Problem: Diagram shows isolated nodes instead of a connected workflow.
Cause: Typo in input/output names - they must match exactly.
Solution: Check that output of one node matches input of the next:
# WRONG - Names don't match
# put id:"step1", output:"data.csv" # Outputs "data.csv"
# put id:"step2", input:"Data.csv" # Expects "Data.csv" (case mismatch!)
# CORRECT - Exact match
# put id:"step1", output:"data.csv"
# put id:"step2", input:"data.csv"Diagnostic:
Frequency: 🟡 Occasional
Problem: Mermaid code appears as text instead of a diagram.
Cause: Mermaid.js not loaded, or syntax error in generated code.
Solution:
_pkgdown.yml# Get raw Mermaid code to debug
mermaid_code <- put_diagram(workflow, output = "raw")
cat(mermaid_code) # Copy this to mermaid.live to testFrequency: 🟡 Occasional
Problem: put_auto() doesn’t detect file
reads/writes you expected.
Cause: Library or function not in detection patterns.
Solution:
patterns <- get_detection_patterns("r")
# Search for your function
grep("readr", sapply(patterns$input, `[[`, "func"), value = TRUE)Frequency: 🟢 Rare
Problem: File parsed with wrong comment syntax.
Cause: Unusual file extension or ambiguous extension
(e.g., .m for MATLAB vs Objective-C).
Solution:
# Check what language is detected for your extension
ext_to_language("m") # Returns "matlab"
ext_to_language("jl") # Returns "julia"
# List all supported extensions
get_supported_extensions()If your extension isn’t recognized, use the standard extension or add manual annotations with the correct comment prefix.
Before diving into specific issues, run these quick checks:
library(putior)
# 1. Check if annotations are found
workflow <- put("./src/", validate = TRUE, include_line_numbers = TRUE)
nrow(workflow) # Should be > 0 if annotations exist
# 2. Test a single annotation
is_valid_put_annotation('# put id:"test", label:"Test Node"') # Should be TRUE
# 3. Check supported extensions
get_supported_extensions()
# 4. Enable detailed logging
set_putior_log_level("DEBUG")
workflow <- put("./src/") # Now shows detailed outputProblem: Annotation is not recognized or properties are missing.
# WRONG - No quotes around values
# put id:my_node, label:My Process
# WRONG - Mismatched quotes
# put id:"my_node', label:"My Process"
# WRONG - Missing closing quote
# put id:"my_node, label:"My Process"Solution: Always use matching quotes around all values.
# CORRECT - Double quotes
# put id:"my_node", label:"My Process"
# CORRECT - Single quotes
# put id:'my_node', label:'My Process'
# CORRECT - Mixed (but consistent per value)
# put id:"my_node", label:'My Process'Diagnostic:
Problem: Validation warning about unusual node_type.
Solution: Use standard node types for consistency.
# Standard node types
# put id:"step1", label:"Load Data", node_type:"input"
# put id:"step2", label:"Transform", node_type:"process"
# put id:"step3", label:"Save Results", node_type:"output"
# put id:"step4", label:"Check Quality", node_type:"decision"
# put id:"step5", label:"Start Pipeline", node_type:"start"
# put id:"step6", label:"End Pipeline", node_type:"end"Note: Custom node types work but generate warnings.
Suppress with validate = FALSE:
Problem: Values containing commas are truncated.
Solution: Enclose values with commas in quotes.
Problem: Warning about empty ID.
# WRONG - Empty ID string
# put id:"", label:"My Process"
# OK - Missing ID (auto-generated UUID)
# put label:"My Process"Solution: Either omit the ID entirely (auto-generated) or provide a valid one.
Problem: Warning about duplicate node IDs.
# In file1.R
# put id:"load_data", label:"Load from CSV"
# In file2.R
# put id:"load_data", label:"Load from JSON" # DUPLICATE!Solution: Use unique IDs across all files in your workflow.
Problem: Multiline annotations not being parsed correctly.
# WRONG - Missing backslash
# put id:"step1", label:"Process",
# input:"data.csv", output:"results.csv"
# WRONG - Backslash not at end of line
# put id:"step1", label:"Process", \
# input:"data.csv"
# WRONG - Missing comment prefix on continuation
# put id:"step1", label:"Process", \
input:"data.csv"Solution: Use proper multiline syntax.
# CORRECT - Backslash at end, comment prefix on each line
# put id:"step1", label:"Process Data", \
# input:"data.csv,config.json", \
# output:"results.csv"For SQL files:
For JavaScript files:
Problem: put() returns empty result or
“no files found” warning.
workflow <- put("./src/")
#> Warning: No files matching pattern '\.(R|r|py|sql|sh|jl)$' found in: ./src/Diagnostic Steps:
# 1. Check if directory exists
dir.exists("./src/")
# 2. List files in directory
list.files("./src/", recursive = TRUE)
# 3. Check what patterns match
list.files("./src/", pattern = "\\.(R|r|py)$")Solutions:
Problem: Your files use extensions not in the default pattern.
# Default pattern only matches: R, r, py, sql, sh, jl
workflow <- put("./src/") # Won't find .js, .ts, .go filesSolution: Specify a custom pattern for your file types.
# JavaScript/TypeScript files
workflow <- put("./src/", pattern = "\\.(js|ts|jsx|tsx)$")
# Go files
workflow <- put("./src/", pattern = "\\.go$")
# Rust files
workflow <- put("./src/", pattern = "\\.rs$")
# Multiple languages
workflow <- put("./src/", pattern = "\\.(R|py|js|ts|go|rs)$")
# All supported extensions
all_exts <- paste(get_supported_extensions(), collapse = "|")
pattern <- paste0("\\.(", all_exts, ")$")
workflow <- put("./src/", pattern = pattern)Problem: Files not found due to case mismatch.
# Pattern is case-sensitive by default
list.files("./src/", pattern = "\\.R$") # Finds script.R
list.files("./src/", pattern = "\\.r$") # Finds script.rSolution: Include both cases in pattern.
# Match both .R and .r
workflow <- put("./src/", pattern = "\\.(R|r)$")
# Or use the default pattern which includes both
workflow <- put("./src/") # Default: "\\.(R|r|py|sql|sh|jl)$"Problem: Diagram doesn’t render or shows syntax error.
Diagnostic:
# Get raw Mermaid code to inspect
workflow <- put("./src/")
mermaid_code <- put_diagram(workflow, output = "raw")
cat(mermaid_code)Common Causes:
# Problem: Quotes in labels
# put id:"step1", label:"Load "raw" data"
# Solution: Use single quotes or escape
# put id:"step1", label:"Load 'raw' data"
# put id:"step1", label:"Load raw data"Problem: Diagram colors don’t appear or look wrong.
# Check available themes
get_diagram_themes()
#> $light, $dark, $auto, $minimal, $github
#> $viridis, $magma, $plasma, $cividis (colorblind-safe)Solutions:
# Try a different theme
put_diagram(workflow, theme = "github")
put_diagram(workflow, theme = "minimal")
# Disable node styling for plain diagrams
put_diagram(workflow, style_nodes = FALSE)
# Check if theme is compatible with your viewer
# "github" works best on GitHub README
# "dark" for dark mode applications
# "minimal" for printing/PDFs
# "viridis", "magma", "plasma", "cividis" for colorblind accessibilityProblem: Nodes appear but arrows don’t connect them.
Cause: Input/output values don’t match between nodes.
# Problem: Typo in file name
# put id:"step1", output:"data.csv"
# put id:"step2", input:"Data.csv" # Case mismatch!
# Solution: Match exactly
# put id:"step1", output:"data.csv"
# put id:"step2", input:"data.csv"Diagnostic:
Problem: Annotations not found in SQL, JavaScript, or other files.
Cause: Using wrong comment syntax for the language.
-- WRONG for SQL - using hash instead of dash
# put id:"query", label:"Run Query"
-- CORRECT for SQL
-- put id:"query", label:"Run Query"// WRONG for JavaScript - using hash
# put id:"handler", label:"Handle Request"
// CORRECT for JavaScript
// put id:"handler", label:"Handle Request"Check the correct prefix:
| Extension | Comment Prefix | Example |
|---|---|---|
.R, .r |
# |
# put id:"step", label:"Process" |
.py |
# |
# put id:"step", label:"Process" |
.sql |
-- |
-- put id:"query", label:"Query" |
.js, .ts |
// |
// put id:"func", label:"Function" |
.go |
// |
// put id:"main", label:"Main" |
.rs |
// |
// put id:"fn", label:"Handler" |
.m (MATLAB) |
% |
% put id:"calc", label:"Compute" |
.tex |
% |
% put id:"sec", label:"Section" |
.sh |
# |
# put id:"cmd", label:"Command" |
.lua |
-- |
-- put id:"fn", label:"Function" |
Problem: File type not automatically recognized.
# Check if extension is supported
ext <- "xyz"
get_comment_prefix(ext) # Returns "#" as fallback
# List all supported extensions
get_supported_extensions()Escape Hatches for Unsupported File Types:
Option 1: Use fallback # prefix (if
your language supports # comments)
# In your .xyz file (if it supports # comments)
# put id:"step1", label:"Process Data"
Option 2: Create a wrapper annotation file
# workflow-annotations.R
# This file documents the workflow for unsupported file types
# put id:"xyz_step1", label:"Process in XYZ format", input:"data.xyz", output:"result.xyz"
# put id:"xyz_step2", label:"Convert output", input:"result.xyz", output:"final.csv"
# Then scan this file instead
workflow <- put("workflow-annotations.R")Option 3: Use text input for ad-hoc annotations
# Define workflow without files
workflow <- put(text = '
# put id:"step1", label:"Custom Step 1", output:"data.xyz"
# put id:"step2", label:"Custom Step 2", input:"data.xyz"
')
put_diagram(workflow)Option 4: Request new language support
Open a GitHub issue with: - Language name and file extension - Comment syntax used by the language - Example code showing typical file I/O patterns (for auto-detection)
Problem: put() takes too long on large
projects.
Solutions:
# 1. Limit to specific directories
workflow <- put("./src/core/") # Instead of ./
# 2. Use specific file patterns
workflow <- put("./src/", pattern = "\\.R$") # Only R files
# 3. Limit to top-level directory if subdirs not needed
workflow <- put("./src/", recursive = FALSE)
# 4. Disable validation for faster scanning
workflow <- put("./src/", validate = FALSE)Problem: Many nodes cause memory or rendering issues.
Solutions:
# 1. Split into smaller subgraphs
workflow_etl <- put("./src/etl/")
workflow_ml <- put("./src/ml/")
# Generate separate diagrams
put_diagram(workflow_etl, file = "etl_workflow.md")
put_diagram(workflow_ml, file = "ml_workflow.md")
# 2. Hide artifacts for cleaner diagrams
put_diagram(workflow, show_artifacts = FALSE)
# 3. Use simpler theme
put_diagram(workflow, theme = "minimal", style_nodes = FALSE)Best Practices:
# Annotate key steps only, not every function
# Good: Major pipeline stages
# put id:"ingest", label:"Data Ingestion", node_type:"input"
# put id:"transform", label:"Data Transformation", node_type:"process"
# put id:"export", label:"Export Results", node_type:"output"
# Avoid: Every small helper function
# (Don't annotate utility functions unless they're significant)| Level | Information Shown |
|---|---|
DEBUG |
File-by-file processing, pattern matching, parsing steps |
INFO |
Scan started, files found, nodes extracted, diagram generated |
WARN |
Validation issues, missing dependencies |
ERROR |
Fatal errors that stop execution |
# Problem: Annotations not being found
# 1. Enable debug logging
set_putior_log_level("DEBUG")
# 2. Run the scan
workflow <- put("./problem_file.R", include_line_numbers = TRUE)
# 3. Check the logs for:
# - "No PUT annotations found in..." (wrong syntax?)
# - "Found X PUT annotation(s)..." (they exist!)
# - "Processing file:..." (file is being scanned)
# 4. Reset to normal
set_putior_log_level("WARN")If you don’t have the logger package installed, putior
works silently without logging. Install it for debugging:
install.packages("logger")
# Verify it's working
library(logger)
set_putior_log_level("INFO")
workflow <- put("./src/")
#> INFO [2024-01-15 10:30:00] Starting PUT annotation scan
#> INFO [2024-01-15 10:30:00] Found 3 file(s) to scan
#> INFO [2024-01-15 10:30:01] Scan complete: found 5 workflow node(s)A: Check these common causes:
list.files())# put not # PUT)A: Use matching input/output file names:
A: putior automatically uses the file name as the output.
A: Yes, putior works in headless environments:
A: Use the .internal extension:
# Variables created during script execution
# put id:"create", output:"dataset.internal, dataset.RData"
dataset <- data.frame(x = 1:100)
save(dataset, file = "dataset.RData")
# Next script uses the saved file, not .internal
# put id:"analyze", input:"dataset.RData", output:"results.internal"
load("dataset.RData")
results <- summary(dataset)Important: .internal files can only be
outputs, never inputs between scripts.
A: Different Mermaid renderers interpret themes differently.
If you’re still stuck:
Check the vignettes:
Use the sandbox:
Enable debug logging and check output carefully
Report issues on GitHub with:
R.version.string)packageVersion("putior"))| Guide | Description |
|---|---|
| Quick Start | First diagram in 2 minutes |
| Annotation Guide | Complete syntax reference |
| Features Tour | Auto-detection, themes, logging |
| API Reference | Function documentation |
| Showcase | Real-world examples |
| Quick Reference | At-a-glance reference card |
| AI Integration | MCP/ACP integration guide |