- Published on
ComfyUI 워크플로 JSON 깨짐 복구 실전
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
ComfyUI를 오래 쓰다 보면 어느 날 갑자기 워크플로 JSON이 열리지 않거나, Load 시 에러가 나면서 노드가 통째로 사라지는 경험을 하게 됩니다. 특히 대형 워크플로(노드 수가 많고, 커스텀 노드가 섞이고, 프롬프트 메타데이터까지 포함된 경우)일수록 저장/복사/전송 과정에서 JSON이 쉽게 깨집니다.
이 글에서는 “깨진 ComfyUI 워크플로 JSON”을 최대한 원형에 가깝게 복구하는 실전 절차를 다룹니다. 단순히 JSON 포맷터 돌리는 수준이 아니라, 잘린 파일(EOF truncate), 잘못된 따옴표/역슬래시, 인코딩 문제, 중복/누락 괄호까지 현실적으로 자주 만나는 케이스를 기준으로 정리합니다.
운영 관점에서의 장애 대응 루틴도 중요합니다. 비슷한 맥락으로 배포 스크립트의 실패를 조기에 잡는 방법은 bash set -euo pipefail로 배포 스크립트 실패 잡기도 참고할 만합니다.
1) ComfyUI 워크플로 JSON이 깨지는 대표 원인
1-1. 저장 중 강제 종료로 인한 파일 잘림
- 브라우저 탭 강제 종료
- ComfyUI 서버 재시작/크래시
- 네트워크 끊김(원격 접속 환경)
이 경우 파일 끝부분이 잘려서 } 나 ]가 부족합니다. 가장 흔한 형태입니다.
1-2. 메신저/노트 앱 복붙으로 인한 이스케이프 파손
- Slack/Notion/메일에 붙여넣는 과정에서
\n,\uXXXX같은 이스케이프가 변형 - “스마트 따옴표”로
"가“”로 바뀜
1-3. 커스텀 노드 업데이트로 스키마가 달라짐
JSON은 정상인데, 특정 노드 타입이 없어 로딩이 실패하거나 일부 노드가 누락된 것처럼 보일 수 있습니다.
1-4. JSON이 아닌 것을 JSON로 착각
ComfyUI에서 공유되는 파일/텍스트는 크게 3종류가 섞입니다.
- 워크플로 JSON
- API 프롬프트 JSON(서버에
prompt로 보내는 형태) - 이미지에 박힌 메타데이터(Compressed/Encoded)
서로 구조가 달라서 “유효한 JSON인데 ComfyUI에서 안 열림”이 발생할 수 있습니다.
2) 복구 전, 반드시 해야 할 안전 조치
- 깨진 파일을 원본 그대로 복사해 보관
- 편집은 복사본에서만 진행
- 가능하면 Git으로 버전 관리(워크플로도 코드처럼 다루는 게 최선)
cp workflow.json workflow.json.bak
# 가능하면 폴더를 git으로 관리
git init
git add workflow.json.bak
git commit -m "backup broken workflow"
3) 1차 진단: JSON이 정말 깨졌는지 빠르게 확인
3-1. jq로 파싱 테스트
가장 빠르고 확실합니다.
jq . workflow.json > /dev/null
# 성공하면 exit code 0
# 실패하면 에러 위치(라인/컬럼)가 나옵니다.
에러가 parse error: Unfinished JSON term at EOF 류면 거의 100% 파일이 잘린 케이스입니다.
3-2. Python으로 에러 위치 확인
jq가 없다면 Python으로도 충분합니다.
python - <<'PY'
import json, sys
p='workflow.json'
try:
json.load(open(p,'r',encoding='utf-8'))
print('OK')
except Exception as e:
print('FAIL:', e)
PY
4) 잘린 JSON(EOF truncate) 복구: 괄호 균형 맞추기
잘린 파일은 “끝이 없다”가 문제이므로, 괄호/대괄호 균형을 맞춰 닫아주는 방식이 1차 복구로 가장 효과적입니다.
4-1. 간단 스크립트: 부족한 } ] 자동 보정
아래 스크립트는 문자열 리터럴 내부는 최대한 건드리지 않고(완벽하진 않지만), 전체 텍스트에서 { } [ ] 수를 보고 부족한 닫는 괄호를 뒤에 붙입니다.
# fix_brackets.py
import sys
src = open(sys.argv[1], 'r', encoding='utf-8', errors='replace').read()
open_curly = src.count('{')
close_curly = src.count('}')
open_square = src.count('[')
close_square = src.count(']')
need_curly = max(0, open_curly - close_curly)
need_square = max(0, open_square - close_square)
fixed = src + (']' * need_square) + ('}' * need_curly)
out = sys.argv[2]
open(out, 'w', encoding='utf-8').write(fixed)
print('added ]:', need_square, 'added }:', need_curly)
python fix_brackets.py workflow.json workflow.fixed.json
jq . workflow.fixed.json > /dev/null && echo "parse ok"
이게 통과되면, 일단 JSON은 다시 “읽히는 상태”가 됩니다. 다만 마지막 오브젝트가 중간에 잘렸다면(예: 문자열이 반만 남음), 파싱이 여전히 실패할 수 있습니다.
4-2. 마지막이 문자열 중간에서 잘린 경우: 마지막 라인 절단
문자열이 열려 있는 상태로 파일이 끝나면, 괄호를 붙여도 파싱이 안 됩니다. 이때는 마지막으로 완결된 구조까지만 남기고 버리는 방식이 현실적입니다.
전략은 다음과 같습니다.
- 파서가 에러를 내는 위치(라인/컬럼) 근처를 확인
- 마지막 몇 줄을 과감히 삭제하고 다시 시도
# 마지막 50줄을 별도 파일로 확인
tail -n 50 workflow.json | nl -ba
# (예시) 마지막 10줄을 제거한 새 파일 생성
head -n -10 workflow.json > workflow.trim.json
jq . workflow.trim.json > /dev/null
이 방식은 일부 노드/설정이 유실될 수 있지만, “아예 못 여는 상태”를 “대부분 열리는 상태”로 바꾸는 데 유효합니다.
5) 따옴표/이스케이프 깨짐 복구: 스마트 따옴표, 역슬래시
5-1. 스마트 따옴표를 ASCII 따옴표로 치환
Notion/문서 편집기에서 흔합니다.
python - <<'PY'
import re
p='workflow.json'
s=open(p,'r',encoding='utf-8',errors='replace').read()
# 스마트 따옴표 치환
s=s.replace('“','"').replace('”','"').replace('’',"'").replace('‘',"'")
open('workflow.quotes.fixed.json','w',encoding='utf-8').write(s)
print('done')
PY
jq . workflow.quotes.fixed.json > /dev/null
5-2. 역슬래시가 소실된 경우
예를 들어 \n이 실제 줄바꿈으로 변해 JSON 문자열이 깨지는 경우가 있습니다. 이건 자동 복구가 까다롭고, 보통은 **깨진 문자열이 들어간 필드(예: prompt 텍스트)**를 찾아서 해당 문자열을 통째로 다시 감싸거나 제거해야 합니다.
팁:
jq에러 위치 라인을 기준으로 해당 줄을 열어보면, 문자열이 중간에 끊겨 있는 경우가 많습니다.- 복구 우선순위는 “워크플로 구조(nodes/links)”를 살리는 것이고, 프롬프트 텍스트 일부는 포기하는 게 시간 대비 효율적입니다.
6) “JSON은 정상인데 ComfyUI에서 안 열림” 케이스
JSON 파싱은 되는데 ComfyUI에서 로딩이 실패한다면, 구조 문제가 아니라 노드 정의/버전 문제일 가능성이 큽니다.
6-1. 커스텀 노드 누락
- 워크플로에 포함된 커스텀 노드 레포가 설치되지 않았거나
- 업데이트로 노드 이름/입출력 포트가 변경
대응:
- 워크플로를 만든 환경의
custom_nodes목록을 확인 - 동일한 커밋/버전으로 맞추기
- 그래도 안 되면 JSON에서 해당 노드 타입을 검색해 대체 노드로 수동 교체
6-2. API 프롬프트 JSON과 워크플로 JSON 혼동
ComfyUI는 “워크플로”와 “프롬프트(API용)” JSON의 키 구조가 다릅니다. 파일 상단에 nodes 배열이 없다면 워크플로가 아닐 수 있습니다.
jq 'keys' workflow.json
# nodes, links, groups 같은 키가 보이면 워크플로일 가능성이 큼
7) 자동 복구 파이프라인: 진단부터 수정까지 한 번에
아래는 실무적으로 자주 쓰는 흐름입니다.
jq파싱 실패면- 스마트 따옴표 치환
- EOF 잘림이면 괄호 보정
- 그래도 실패하면 마지막 라인/블록 절단
jq파싱 성공인데 ComfyUI 로드 실패면- 커스텀 노드 설치/버전 정렬
- 문제 노드 타입 찾아 제거/대체
간단한 셸 파이프라인 예시:
set -euo pipefail
in=workflow.json
step1=workflow.step1.json
step2=workflow.step2.json
# 1) 스마트 따옴표 정리
python - <<'PY'
import sys
p=sys.argv[1]
out=sys.argv[2]
s=open(p,'r',encoding='utf-8',errors='replace').read()
s=s.replace('“','"').replace('”','"').replace('’',"'").replace('‘',"'")
open(out,'w',encoding='utf-8').write(s)
PY "$in" "$step1"
# 2) 괄호 보정
python - <<'PY'
import sys
src=open(sys.argv[1],'r',encoding='utf-8',errors='replace').read()
need_square=max(0, src.count('[')-src.count(']'))
need_curly=max(0, src.count('{')-src.count('}'))
fixed=src + (']'*need_square) + ('}'*need_curly)
open(sys.argv[2],'w',encoding='utf-8').write(fixed)
print('added ]',need_square,'added }',need_curly)
PY "$step1" "$step2"
# 3) 파싱 확인
jq . "$step2" > /dev/null
echo "Recovered JSON is parseable: $step2"
set -euo pipefail은 이런 “중간 실패를 즉시 감지”하는 자동화에 특히 유용합니다. 자세한 배경은 bash set -euo pipefail로 배포 스크립트 실패 잡기에서 더 깊게 다룹니다.
8) 재발 방지: 워크플로를 ‘아티팩트’로 관리하기
8-1. 저장 습관
- 큰 변경 전후로 파일을 별도 이름으로 저장(스냅샷)
- 원격 접속이면 네트워크 불안정 구간에서 저장/다운로드를 피하기
8-2. Git + 작은 커밋
워크플로도 코드처럼 다루면 복구 난이도가 급감합니다.
git add workflow.json
git commit -m "tune sampler and cfg"
8-3. 자동 백업(타임스탬프 복사)
mkdir -p backups
cp workflow.json "backups/workflow.$(date +%Y%m%d-%H%M%S).json"
8-4. 장애 대응 관점의 공통 원칙
JSON 깨짐 복구는 본질적으로 “원인 파악 → 최소 변경으로 정상화 → 재발 방지”의 루틴입니다. 이런 루틴은 인프라 장애에도 그대로 적용됩니다. 예를 들어 서비스가 반복 재시작하는 상황에서 원인을 좁히는 방법은 systemd 재시작 루프(StartLimitHit) 해결법도 같은 결을 갖습니다.
9) 체크리스트: 가장 빠른 복구 순서
jq . file.json으로 파싱 여부 확인- EOF 잘림이면 괄호 보정 스크립트 적용
- 문자열 중간 잘림이면 마지막 블록 절단 후 재시도
- 스마트 따옴표/복붙 흔적이 있으면 따옴표 치환
- 파싱은 되는데 로딩이 안 되면 커스텀 노드/버전부터 맞추기
- 복구 후에는 즉시 백업 및 Git 커밋
마무리
ComfyUI 워크플로 JSON 깨짐은 “한 번도 안 겪는 사람은 있어도, 한 번만 겪는 사람은 드문” 유형의 사고입니다. 중요한 건 완벽한 복원보다, 워크플로 구조를 다시 열 수 있는 상태로 빠르게 되돌리는 것입니다. 위의 진단(jq)과 2단계 복구(따옴표 정리, 괄호 보정), 그리고 최후의 수단(마지막 블록 절단)만 익혀도 대부분의 케이스는 시간 내 복구가 가능합니다.
다음에 같은 문제가 다시 생기지 않도록, 워크플로를 Git으로 관리하고 자동 백업을 붙이는 순간부터 복구는 ‘사건’이 아니라 ‘절차’가 됩니다.