Skip to main content الرئيسية المنشئون jeremylongshore tons-of-skills-marketplace adobe-known-pitfalls
adobe-known-pitfalls Identify and avoid Adobe-specific anti-patterns: using deprecated JWT auth,
not caching IMS tokens, ignoring Firefly content policy, missing async job
polling, and leaking p8_ secrets. Real code examples with fixes.
Trigger with phrases like "adobe mistakes", "adobe anti-patterns",
"adobe pitfalls", "adobe what not to do", "adobe code review".
الانتقال إلى التثبيت سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/jeremylongshore/tons-of-skills-marketplace --skill adobe-known-pitfallsيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... المزيد من هذا المستودع langchain-deploy-integration Deploy a LangChain 1.0 / LangGraph 1.0 app to Cloud Run, Vercel, or LangServe correctly — with timeouts sized for chain length, cold-start mitigation, SSE anti-buffering headers, and Secret Manager over .env. Use when prepping a first production deploy, debugging a stream that hangs behind a proxy, or diagnosing p99 latency spikes. Trigger with "langchain deploy", "langchain cloud run", "langchain vercel python", "langchain langserve", or "langchain docker".
langchain-langgraph-agents Build a correct LangGraph 1.0 ReAct agent with create_react_agent — typed tools, error propagation, recursion caps, and stop conditions that actually stop. Use when writing a first tool-calling agent, migrating from AgentExecutor or initialize_agent, or diagnosing an agent that loops on vague prompts. Trigger with "langgraph agent", "create_react_agent", "langgraph tool calling", "AgentExecutor migration", or "agent loop cost".
langchain-langgraph-human-in-loop Build LangGraph 1.0 human-in-the-loop approval flows with interrupt_before /
interrupt_after and Command(resume=...) — JSON-serializable state, clean
resume semantics, and UI wiring for approval decisions. Use when adding an
approval gate before an expensive tool call, wiring a Slack/web UI for agent
approvals, or debugging a graph that crashes on interrupt.
Trigger with "langgraph human in loop", "langgraph interrupt_before",
"langgraph approval flow", "Command resume", "langgraph HITL".
name adobe-known-pitfalls description Identify and avoid Adobe-specific anti-patterns: using deprecated JWT auth,
not caching IMS tokens, ignoring Firefly content policy, missing async job
polling, and leaking p8_ secrets. Real code examples with fixes.
Trigger with phrases like "adobe mistakes", "adobe anti-patterns",
"adobe pitfalls", "adobe what not to do", "adobe code review".
allowed-tools Read, Grep version 1.7.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","design","adobe"] compatibility Designed for Claude Code
Adobe Known Pitfalls
Overview
The 10 most common mistakes when integrating with Adobe APIs, based on real production issues. Each pitfall includes the anti-pattern, why it fails, and the correct approach.
Prerequisites
Access to your Adobe integration codebase
Understanding of Adobe API architecture (OAuth, async jobs, rate limits)
Instructions
Pitfall 1: Still Using JWT (Service Account) Credentials
Status: CRITICAL — JWT credentials reached End of Life June 2025.
import jwt from 'jsonwebtoken' ;
import fs from 'fs' ;
const privateKey = fs.readFileSync ('private.key' );
const jwtToken = jwt.sign ({
exp : Math .round (Date .now () / 1000 ) + 86400 ,
iss : orgId,
sub : technicalAccountId,
aud : `https://ims-na1.adobelogin.com/c/${clientId} ` ,
}, privateKey, { algorithm : 'RS256' });
const res = await fetch ('https://ims-na1.adobelogin.com/ims/token/v3' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/x-www-form-urlencoded' },
body : new URLSearchParams ({
: process. . !,
: process. . !,
: ,
: process. . !,
}),
});
client_id
env
ADOBE_CLIENT_ID
client_secret
env
ADOBE_CLIENT_SECRET
grant_type
'client_credentials'
scope
env
ADOBE_SCOPES
Pitfall 2: Not Caching IMS Access Tokens IMS tokens are valid for 24 hours. Generating a new token per request wastes 200-500ms:
async function callFirefly (prompt : string ) {
const tokenRes = await fetch ('https://ims-na1.adobelogin.com/ims/token/v3' , { ... });
const { access_token } = await tokenRes.json ();
}
let cached : { token : string ; expiresAt : number } | null = null ;
async function getToken ( ): Promise <string > {
if (cached && cached.expiresAt > Date .now () + 300_000 ) return cached.token ;
const res = await fetch ('https://ims-na1.adobelogin.com/ims/token/v3' , { ... });
const data = await res.json ();
cached = { token : data.access_token , expiresAt : Date .now () + data.expires_in * 1000 };
return cached.token ;
}
Pitfall 3: Using Firefly Sync Endpoint for Batch Operations
for (const prompt of prompts) {
const result = await fetch ('https://firefly-api.adobe.io/v3/images/generate' , {
method : 'POST' , ...
});
results.push (await result.json ());
}
const jobs = await Promise .all (
prompts.map (prompt =>
fetch ('https://firefly-api.adobe.io/v3/images/generate-async' , {
method : 'POST' , ...
}).then (r => r.json ())
)
);
const results = await Promise .all (jobs.map (j => pollJob (j.statusUrl )));
Pitfall 4: Ignoring Firefly Content Policy Errors
try {
const result = await generateImage ({ prompt : 'Photo of Nike shoes' });
} catch (e) {
console .log ('Generation failed' );
}
try {
const result = await generateImage ({ prompt });
} catch (e : any ) {
if (e.status === 400 && e.message ?.includes ('content policy' )) {
throw new Error (
'Firefly content policy violation. ' +
'Remove trademarks, real people, or explicit content from prompt.'
);
}
throw e;
}
Pitfall 5: Uploading Files Directly to Photoshop/Lightroom API
const formData = new FormData ();
formData.append ('image' , fs.readFileSync ('photo.jpg' ));
await fetch ('https://image.adobe.io/v2/remove-background' , {
method : 'POST' ,
body : formData,
});
const inputUrl = await s3.getSignedUrl ('getObject' , {
Bucket : 'my-bucket' , Key : 'photo.jpg' , Expires : 3600 ,
});
const outputUrl = await s3.getSignedUrl ('putObject' , {
Bucket : 'my-bucket' , Key : 'output.png' , Expires : 3600 ,
});
await fetch ('https://image.adobe.io/v2/remove-background' , {
method : 'POST' ,
headers : { Authorization : `Bearer ${token} ` , 'x-api-key' : clientId, 'Content-Type' : 'application/json' },
body : JSON .stringify ({
input : { href : inputUrl, storage : 'external' },
output : { href : outputUrl, storage : 'external' , type : 'image/png' },
}),
});
Pitfall 6: Not Polling Async Job Status Photoshop and Lightroom APIs return immediately with a job ID. You must poll for results:
const res = await fetch ('https://image.adobe.io/v2/remove-background' , { ... });
const result = await res.json ();
console .log ('Done!' , result);
const submission = await res.json ();
let job;
do {
await new Promise (r => setTimeout (r, 2000 ));
const pollRes = await fetch (submission._links .self .href , {
headers : { Authorization : `Bearer ${token} ` , 'x-api-key' : clientId },
});
job = await pollRes.json ();
} while (job.status !== 'succeeded' && job.status !== 'failed' );
if (job.status === 'failed' ) throw new Error (job.error ?.message );
Pitfall 7: Leaking Adobe Credentials in Source Code
const client_secret = 'p8_XYZ_your_actual_secret_here_do_not_do_this' ;
const client_secret = process.env .ADOBE_CLIENT_SECRET !;
Pitfall 8: Not Handling PDF Services Quota
async function extractAllPdfs (paths : string [] ) {
for (const path of paths) {
await extractPdf (path);
}
}
let txCount = 0 ;
async function trackedExtract (path : string ) {
if (txCount >= 490 ) {
throw new Error ('Approaching PDF Services monthly limit. 10 transactions remaining.' );
}
const result = await extractPdf (path);
txCount++;
return result;
}
Pitfall 9: Using Deprecated Photoshop Endpoints
await fetch ('https://image.adobe.io/sensei/cutout' , { ... });
await fetch ('https://image.adobe.io/v2/remove-background' , { ... });
Pitfall 10: Missing Webhook Signature Verification
app.post ('/webhooks/adobe' , (req, res ) => {
processEvent (req.body );
res.sendStatus (200 );
});
app.post ('/webhooks/adobe' , express.raw ({ type : 'application/json' }), async (req, res) => {
const sig = req.headers ['x-adobe-digital-signature-1' ];
const keyPath = req.headers ['x-adobe-public-key1-path' ];
const publicKey = await fetch (`https://static.adobeioevents.com${keyPath} ` ).then (r => r.text ());
const verifier = crypto.createVerify ('RSA-SHA256' );
verifier.update (req.body );
if (!verifier.verify (publicKey, sig, 'base64' )) {
return res.sendStatus (401 );
}
processEvent (JSON .parse (req.body .toString ()));
res.sendStatus (200 );
});
Quick Pitfall Scanner
echo "=== Adobe Pitfall Scan ==="
grep -rn "jsonwebtoken\|jwt\.sign\|RS256" --include="*.ts" --include="*.js" src/ && echo "FOUND: JWT auth (deprecated)" || echo "OK: No JWT"
grep -rn "ims/token/v3" --include="*.ts" src/ | wc -l | xargs -I{} echo "Token endpoint calls: {} (should be 1 — in auth.ts only)"
grep -rn "p8_" --include="*.ts" --include="*.js" src/ && echo "FOUND: Hardcoded Adobe secret" || echo "OK: No hardcoded secrets"
grep -rn "sensei/cutout" --include="*.ts" src/ && echo "FOUND: Deprecated Photoshop endpoint" || echo "OK: No deprecated endpoints"
grep -rn "webhooks/adobe" --include="*.ts" src/ | grep -v "digital-signature\|verify\|RSA" && echo "WARNING: Webhook handler may lack signature verification"
Quick Reference Card Pitfall Risk Detection Fix JWT auth Broken auth Grep for jwt.sign Migrate to OAuth S2S No token cache Perf (-500ms/req) Multiple ims/token calls Cache with expiry Sync Firefly for batch Slow (N*20s) Sequential generate calls Use async endpoint Ignore content policy Wasted credits Catch 400 without reason Pre-screen prompts Direct file upload 400 errors FormData to Photoshop Pre-signed URLs No job polling Missing results No poll loop after submit Poll _links.self Leaked p8_ secret Credential compromise Grep for p8_ Env vars + .gitignore No quota tracking Silent failures No counter Track per-month usage Old PS endpoint 404 errors /sensei/cutout/v2/remove-backgroundNo webhook verify Security hole No signature check RSA-SHA256 verification
Output Following this guide produces the Adobe integration outcome for its topic—configuration, validation evidence, operational recovery, or a documented migration result. Record command output and relevant identifiers so a failed step is traceable.
Error Handling If a step fails, stop before applying follow-on changes, retain sanitized diagnostic evidence, and use the troubleshooting or escalation guidance already in this skill. Treat authentication and vendor-service failures separately from local configuration errors.
Examples Start with the smallest applicable command or code example already provided in this guide, using a non-production Adobe environment and credentials. Confirm the documented response or validation result before applying the pattern to production.
Resources