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'
# CORRECT - The other kind of quote inside a value
# put id:"my_node", label:"Don't panic"
# put id:"my_node", label:'Say "hi"'A value cannot contain the kind of quote it is wrapped in; there are
no escapes. put() warns about each property it cannot read
(“Ignored label:…”) unless validate = FALSE.
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 (generated automatically)
# 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:
put_diagram()
escapes quotes and other characters that Mermaid would misread, so a
label may contain them. In the annotation, wrap such a label in the
other kind of quote.# Problem: the label's own quotes end the value, so put() ignores it
# put id:"step1", label:"Load "raw" data"
# Solution: wrap the label in the other kind of quote
# put id:"step1", label:'Load "raw" data'
# put id:"step1", label:"Load 'raw' data"end or class are Mermaid keywords.
put_diagram() writes them as node_end and
node_class, so they work; only the id in the Mermaid code
differs.<Problem: Part of a label is missing, and
put_diagram() warned that a label contains a
< before a letter, /, ! or
?.
Cause: Mermaid draws labels as HTML, so
< followed by a letter (or by /,
! or ?) starts an HTML tag. A tag it does not
know, such as <draft>, disappears, and so does text
that looks like the attributes of a real tag:
a<b and c>d shows “ad”.
Solution: Write < for a
< that should show:
A < followed by a space, a digit or -
(x < 5, x<5, x <- y)
shows as written. Inside $$...$$ math, write
\lt: < and a plain <
make KaTeX fail. Labels may still contain the tags br,
b, i, em, strong,
sub, sup, code and
span on purpose; put_diagram() does not warn
about them. Give their attributes single quotes
(<span style='color:red'>).
< or Loses TextProblem: The title above the diagram shows
<, > or &,
or part of it is missing, and put_diagram() warned that the
title contains <.
Cause: Mermaid passes the title through an HTML
sanitizer. When the title contains a <, the drawn title
shows HTML entities such as <, >
and & for <, > and
&, and text that looks like an HTML tag (such as
<draft>) disappears. No escape avoids that.
Solution: Leave the < out of the
title, or write “less than”. The title that screen readers announce
(accTitle) shows it as written.
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: Data files (artifacts) don’t appear in diagram.
Problem: A large workflow’s diagram is replaced by “Edge limit exceeded”, “Syntax error in text” or a one-node “Maximum text size in diagram exceeded” placeholder.
Mermaid draws at most 500 edges and 50,000 characters by default
(maxEdges, maxTextSize). Both are settings
that only the page can change (mermaid.initialize()); a
diagram cannot raise them, and GitHub, GitLab and Quarto keep the
defaults. put_diagram() warns when its output is over
either limit.
Solutions:
# Fewer edges: leave out the file nodes
put_diagram(workflow, show_artifacts = FALSE)
# A smaller workflow: skip files, or draw a subset of the steps
workflow <- put("./src/", exclude = "legacy/")
put_diagram(workflow[workflow$file_name %in% c("load.R", "clean.R"), ])
# Less text: shorter labels, no styling lines
put_diagram(workflow, node_labels = "name", style_nodes = FALSE)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 |